I have a Java class named, MyClass
, that I want to test with JUnit. The public method, methodA
, that I want to test calls a private method, methodB
, in the same class to determine which conditional path to follow. My goal is to write JUnit tests for the different paths in methodA
. Also, methodB
calls a service, so I do not want it to actually be executed when I run the JUnit tests.
What is the best way to mock methodB
and control its return so that I can test different paths for 'methodA'?
I prefer to use JMockit when writing mocks, so I am specifically interested in any answer that applies to JMockit.
Here is my example class:
public class MyClass {
public String methodA(CustomObject object1, CustomObject object2) {
if(methodB(object1, object2)) {
// Do something.
return "Result";
}
// Do something different.
return "Different Result";
}
private boolean methodB(CustomObject custObject1, CustomObject custObject2) {
/* For the sake of this example, assume the CustomObject.getSomething()
* method makes a service call and therefore is placed in this separate
* method so that later an integration test can be written.
*/
Something thing1 = cobject1.getSomething();
Something thing2 = cobject2.getSomething();
if(thing1 == thing2) {
return true;
}
return false;
}
}
This is what I have so far:
public class MyClassTest {
MyClass myClass = new MyClass();
@Test
public void test_MyClass_methodA_enters_if_condition() {
CustomObject object1 = new CustomObject("input1");
CustomObject object2 = new CustomObject("input2");
// How do I mock out methodB here to return true?
assertEquals(myClass.methodA(object1, object2), "Result");
}
@Test
public void test_MyClass_methodA_skips_if_condition() {
CustomObject object1 = new CustomObject("input1");
CustomObject object2 = new CustomObject("input2");
// How do I mock out methodB here to return false?
assertEquals(myClass.methodA(object1, object2), "Different Result");
}
}
Thanks!
Do not be tempted to mock private methods, even if you can engaging in trickery to do so using a mocking tool. Private members are implementation details, which you should be free to change. Instead use the non-private API to exercise the class. If this is troublesome, consider moving the troublesome code into a different class, if it is not there already, and use dependency injection to inject a mock implementation of the troublesome code.