【发布时间】:2023-03-12 11:59:01
【问题描述】:
我正在尝试为预先存在的课程编写测试。
class ClassToBeTested {
private final Obj1 a;
ClassToBeTested(String anotherVariable) {
a = new Obj1(anotherVariable);
}
public void methodToBeTested() {
if(invokeSomeOtherMethod()) {
a.getAnotherVariable().doSomething();
}
}
public boolean invokeSomeOtherMethod() {
// return true or false based on some logic
}
Obj1 getObj1() {
return a;
}
}
下面是我的测试类:
class TestClass {
@Test
public void testMethod() {
ClassToBeTested x = new ClassToBeTested("someString");
ClassToBeTested spyX = spy(x);
doReturn(false).when(spyX).invokeSomeOtherMethod();
spyX.methodToBeTested();
verify(spyX, times(1)).getObj1().doSomething();
}
}
这是我的理解: 由于 obj1 是在类构造函数中创建的私有最终对象,因此它既不能在测试方法中直接访问,也不能强制 spyObject 使用 obj1 的模拟版本。
此外,由于 verify() 需要 obj1 的模拟版本,因此会引发错误:
Wanted But Not invoked: x.getObj1(), however there are otherInteractions with this mock: x.invokeSomeOtherMethod()
我的理解错了吗?测试 testMoethod() 的方法是什么?
【问题讨论】:
-
修改构造函数以便注入
a? -
我想避免这种情况,因为它需要跨项目中的多个文件进行更改。 a 的初始化也不直接依赖于调用它的代码,因为
anotherVariable只是一个当前未使用的字符串。 -
我不明白你的代码。你的类只显示了一个构造函数——没有没有参数的构造函数。但是您在测试方法中使用了没有参数的构造函数。哪个是对的?
-
对不起...我的错误...已纠正...有一个字符串参数的构造函数。
-
您的问题是您在
spyX对象上调用verify,而您正在尝试验证对Obj1对象的方法调用。可能最简单的做法是添加第二个构造函数,在其中传入Obj1而不是String。然后在您的测试中使用第二个构造函数,并传入一个模拟Obj1,然后您可以对其进行验证。
标签: java unit-testing mocking mockito