我遇到了这种奇怪的情况,即在为
openMocks()
带注释的对象调用 @InjectMocks
后,Mockito 将已经模拟的对象替换为新对象。
这是我的设置:
@RunWith(MockitoJUnitRunner.class) public class MyTest {
@Mock ClassA mockClassA;
@Mock ClassB mockClassB;
@InjectMocks ClassToTest classToTest;
AutoCloseable closeable;
@Before public void openMocks() {
closeable = MockitoAnnotations.openMocks(this);
}
//...
}
public class ClassToTest {
@Inject private ClassA classA;
private final ClassB classB;
@Inject public ClassToTest(ClassB classB) {
this.classB = classB;
}
}
附注我无法控制
ClassToTest
,我无法重写它以将私有成员 classA
移动到构造函数。
这里我想模拟
classA
和classB
,而测试是针对ClassToTest
。由于 classA
不是通过构造函数设置的,因此我需要使用 Mockito 的 @InjectMocks
来为我设置它。它确实通过我在测试中的mockClassA
正确设置了它。
然而,问题出在
classB
。我在 openMocks()
之前设置了一个断点,在那里我可以看到 classToTest.classA
= null
和 classToTest.classB
= mockClassB
,这是预期的。然后在调用openMocks()
之后,我可以看到classToTest.classA
= mockClassA
,这很好。但是 classToTest.classB
现在变成了一个新的模拟对象,不再是 mockClassB
了。由于我需要为 mockClassB
设置模拟返回,因此用新的模拟替换它是行不通的。
有没有办法告诉 Mockito 不要用新的模拟交换
classB
?
@RunWith(MockitoJUnitRunner.class)
应该已经初始化所有 @Mock
和 @InjectMocks
带注释的字段。
仅当您不使用注释且必须手动初始化字段时才需要 MockitoAnnotations.openMocks
。
@RunWith(MockitoJUnitRunner.class)
public class MyTest {
@Mock ClassA mockClassA;
@Mock ClassB mockClassB;
@InjectMocks ClassToTest classToTest;
AutoCloseable closeable;
@Before public void setup() {
when(mockClassB.someCall()).thenReturn(whatever);
}
@Test public void test() {
// use this.classToTest
}
这类似于为什么在执行单元测试时不调用我的模拟方法?(对两个不同模拟对象的不同引用,您的测试引用一个而您的类引用不同的一个)。