【发布时间】:2018-09-23 08:25:54
【问题描述】:
我目前正在尝试测试我的代码的执行路径,但在涉及嵌套类成员变量时遇到了一些问题。考虑以下类结构:
System (System under test)
-> ClassA
-> ClassB
-> ClassC
名为System 的类包含ClassA 的一个实例,并将调用其中一个方法。 ClassA 将同样包含 ClassB 的一个实例,并将调用其中一个方法等。
@RunWith(JMockit.class)
public class SomeTest {
@Tested
private System system;
@Injectable
private ClassA memberA;
@Injectable
private ClassB memberB;
@Injectable
private ClassC memberC;
@Test
public void doSystemTest() {
// Do stuff
system.handle();
new Verifications() {
{
system.handle(); times = 1;
memberA.doSomeAStuff(); times = 1;
memberB.doSomeBStuff(); times = 1; // Results in test failure:
}
};
}
}
当我运行此测试时,我收到以下错误:
缺少 1 次调用: ca.kgli.jmockit.ClassB#doSomeBStuff() 在模拟实例上:ca.kgli.jmockit.ClassB@1a052a00
供参考,代码如下:
public class System {
private ClassA memberA;
public void handle() {
memberA.doSomeAStuff();
}
}
public class ClassA {
private ClassB memberB;
public void doSomeAStuff() {
memberB.doSomeBStuff();
}
}
public class ClassB {
private ClassC member;
public void doSomeBStuff() {
member.stuffCSays("arsenic");
}
}
public class ClassC {
public String stuffCSays(String input) {
return "Hello, " + input;
}
}
所以我的问题是,为什么方法doSomeBStuff 没有被调用? JMockit 不应该以这种方式使用吗?我是这个测试工具包的新手,因此非常感谢任何关于这个问题的帮助或见解。
【问题讨论】:
-
memberA 作为模拟注入,这意味着它的所有方法都没有实现(除非使用结果和返回另外定义)所以 memberA 并没有真正调用 menberB,这在单元测试中是完全可以的。您应该将 System.java 上的测试限制为验证调用是否委派给 memberA。然后有一个 ClassA 测试来验证 memberB 正在被使用,等等
-
谢谢!我想这证实了我一直以来的怀疑。似乎 JMockit 不是为这种方式设计的,这在单元测试的上下文中是有意义的。
-
您正在寻找的是
@Tested(fullyInitialized = true),它允许从调用System#doSystemTest()开始测试所有类,无需模拟。见Getting started。
标签: java unit-testing junit jmockit