我对Mockito没有太多经验-我发现了一些我无法解释的行为:我有一个简单的类,可以这样说
public class Testee {
protected MyParam myParam;
public void myMethod(){
myParam = new MyParam();
myParam.someField = "a new value";
}
此类中的变量myParam
的类型是仅具有一个公共字段的类:
public class MyParam {
public String someField;
}
现在,我想为Testee
类编写一个测试,并且这样做:
@RunWith(PowerMockRunner.class)
public class TestTestee {
@InjectMocks
Testee testee = new Testee();
@Mock
MyParam myParam;
@Test
public void testMyMethod(){
myParam.someField = "old value";
testee.myMethod();
assertEquals("a new value", myParam.someField);
}
}
但是此测试失败!结果消息是:
org.junit.ComparisonFailure:
Expected: a new value
Actual: old value
因此,模拟实际上已正确注入,但似乎没有注意到,实类中的方法将新值写入模拟变量(myParam = new MyParam();
)中。模拟的值保持不变-测试失败。这让我有些困惑,特别是关于如果我仅删除行myParam = new MyParam();
,则测试成功!
因此,该模拟程序无法注意到正在将新对象写入到模拟变量中,但是它确实注意到对该对象所做的更改-我是否正确理解它?在这种情况下,测试由myParam
写入myMethod()
的值的正确方法是什么?
答案 0 :(得分:0)
似乎您实际上并不需要模拟,因为您希望传递具有特定状态的对象。您可能会重新考虑并只使用二传手。
如果您真的必须并且可能需要模拟该类的某些公共方法,则尝试使用间谍代替模拟:
@Spy
MyParam myParam;
现在默认情况下,将调用所有实际的实现,并且您需要显式地模拟某些想要存根的方法。
答案 1 :(得分:0)
之所以发生这种情况,是因为在Testee
中myParam = new MyParam()
的行上,对类成员Testee testee
的引用已重新分配给new MyParam()
。测试中的模拟对象尚未重新分配,仍然指向原始值。
要解决此问题,可以将设置器setSomeField(String someField)
添加到MyParam
中,而不是重新分配值,请在Testee
中调用myParam.setSomeField("a new value")
。
因此,模拟无法注意到有新对象写入了 模拟变量,但它确实注意到对对象所做的更改-我 正确理解吗?
所有关于引用所指向的内存中的对象。在测试中,我们创建了一个模拟,模拟框架将类成员设置为模拟的对象引用。
然后,我们重新分配类成员,但我们的单元测试将检查模拟。模拟对象的引用未更改。