[JAVA] Part of the class called from the class under test in JMockit Mock method memo

Required situation

If you want to Mock only some methods of the class called from the class under test

JMockit 1.46

Conclusion

  1. Pass the instance you want to Mock to Expectations and define only the method you want to Mock in Expectations
  2. Set (forcibly) to the test target class

Tested class

public class Sample {

	@Inject
	Hoge hoge;

	public String getHoge() {
		return hoge.getHoge() + hoge.getHogeUpper();
	}
}

I'm using Hoge's method injected from the class under test. This is a workaround if you want to partially mock the Hoge.

Class called from the class under test

public class Hoge {

	public String getHoge() {
		return "hoge";
	}

	public String getHogeUpper() {
		return null;
	}
}

Please assume that getHoge has been implemented and getHogeUpper has not been implemented yet.

Test failed

public class SampleTest {

	@Tested
	Sample sample;

 	@Injectable
	Hoge hoge;

	/**
	 *A case where you want to Mock only some methods of the class called from the class under test.
	 *The test fails.
	 */
	@Test
	public void test() {

		new Expectations(hoge) {{
			hoge.getHogeUpper();
			result = "HOGE";
		}};

		String actual = sample.getHoge();
		assertThat(actual, is("hogeHOGE")); //actual becomes null HOGE
	}
}

Since the class under test uses Inject, I would normally like to inject instances with @Tested and @Injectable in JMockit, but that would cause the test to fail. The reason is that @Injectable will empty all Hoge methods.

Test successful

public class SampleTest2 {

	Sample sample = new Sample();

	/**
	 *A case where you want to Mock only some methods of the class called from the class under test.
	 *The test succeeds.
	 * @throws Exception
	 * @throws NoSuchFieldException
	 */
	@Test
	public void test() throws NoSuchFieldException, Exception {

		Hoge hoge = new Hoge();
		new Expectations(hoge) {
			{
				hoge.getHogeUpper();
				result = "HOGE";
			}
		};

		//Set a partially Mocked hoge in the private field of Sample
        Field field = sample.getClass().getDeclaredField("hoge");
        field.setAccessible(true);
        field.set(sample, hoge);

		String actual = sample.getHoge();
		assertThat(actual, is("hogeHOGE"));
	}
}

See below for more information on partial Mock. https://jmockit-ja.nyamikan.net/tutorial/Mocking.html#partial The test is successful by setting the partially Mocked Mock instance to the test target class by reflection.

Finally

In older versions of JMockit, only part of it was Mocked with MockUp , and the instance obtained with getMockInstance was set in the test class with Deencapsulation.setField, but in 1.46 both methods disappeared. .. .. Please be careful when updating the version of JMockit, as the API is frequently deleted. Please let me know if there is any other good way.

Recommended Posts

Part of the class called from the class under test in JMockit Mock method memo
How to mock some methods of the class under test
Get the name of the test case in the JUnit test class
Call a method of the parent class by explicitly specifying the name in Ruby
Increment with the third argument of iterate method of Stream class added from Java9
Correspondence of the part where Authentication # getDetails is done in the unit test of spring-security
[Order method] Set the order of data in Rails
[Java] Handling of JavaBeans in the method chain
Java method call from RPG (method call in own class)
Provisional memo when the name of the method parameter of the Java class cannot be obtained by reflection in the Eclipse plug-in project.
A quick review of Java learned in class part4
Return the execution result of Service class in ServiceResponse class
A quick review of Java learned in class part3
A quick review of Java learned in class part2
Why the get method is needed in the Calendar class
Summarize the additional elements of the Optional class in Java 9
How to get the class name / method name running in Java
The story of raising Spring Boot from 1.5 series to 2.1 series part2
JSON in Java and Jackson Part 1 Return JSON from the server
I want to expand the clickable part of the link_to method
The story of throwing BLOB data from EXCEL in DBUnit
[Memo] JSUG Study Group 2019 Part 7 Utilization of Spring in Visional
Memo of JSUG Study Group 2018 Part 2-Efforts for working specifications in the Spring and API era-
[Java beginner] Conversion from character string to numerical value-What is the parseInt method of the Integer class? ~