我有一个名为 MyClass
的 Java 类,我想用 JUnit 对其进行测试。我要测试的公共(public)方法 methodA
调用同一类中的私有(private)方法 methodB
以确定要遵循的条件路径。我的目标是为 methodA
中的不同路径编写 JUnit 测试。此外,methodB
调用一个服务,所以我不希望它在我运行 JUnit 测试时实际执行。
模拟 methodB
并控制其返回以便我可以测试“methodA”的不同路径的最佳方法是什么?
我更喜欢在编写模拟时使用 JMockit,因此我对适用于 JMockit 的任何答案特别感兴趣。
这是我的示例类:
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;
}
}
这是我目前所拥有的:
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");
}
}
谢谢!
最佳答案
给出您要求的答案(使用 JMockit 的部分模拟):
public class MyClassTest
{
@Tested MyClass myClass;
@Test
public void test_MyClass_methodA_enters_if_condition() {
final CustomObject object1 = new CustomObject("input1");
final CustomObject object2 = new CustomObject("input2");
new NonStrictExpectations(myClass) {{
invoke(myClass, "methodB", object1, object2); result = true;
}};
assertEquals("Result", myClass.methodA(object1, object2));
}
@Test
public void test_MyClass_methodA_skips_if_condition() {
final CustomObject object1 = new CustomObject("input1");
final CustomObject object2 = new CustomObject("input2");
new NonStrictExpectations(myClass) {{
invoke(myClass, "methodB", object1, object2); result = false;
}};
assertEquals("Different Result", myClass.methodA(object1, object2));
}
}
但是,我不建议这样做。通常,不应模拟 private
方法。相反,模拟被测单元的实际外部依赖性(在本例中为 CustomObject
):
public class MyTestClass
{
@Tested MyClass myClass;
@Mocked CustomObject object1;
@Mocked CustomObject object2;
@Test
public void test_MyClass_methodA_enters_if_condition() {
new NonStrictExpectations() {{
Something thing = new Something();
object1.getSomething(); result = thing;
object2.getSomething(); result = thing;
}};
assertEquals("Result", myClass.methodA(object1, object2));
}
@Test
public void test_MyClass_methodA_skips_if_condition() {
new NonStrictExpectations() {{
object1.getSomething(); result = new Something();
object2.getSomething(); result = new Something();
}};
assertEquals("Different Result", myClass.methodA(object1, object2));
}
}
关于java - 正在测试的同一类中的模拟私有(private)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19699122/