在为 InjectMocks 带注释的对象调用 openMocks 后,Mockito 将已经模拟的对象替换为新对象

问题描述 投票:0回答:1

我遇到了这种奇怪的情况,即在为

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

java unit-testing dependency-injection mockito guice
1个回答
0
投票

@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
    }

这类似于为什么在执行单元测试时不调用我的模拟方法?(对两个不同模拟对象的不同引用,您的测试引用一个而您的类引用不同的一个)。

© www.soinside.com 2019 - 2024. All rights reserved.