如何模拟 @InjectMocks 类中的方法?

MTQ*_*MTQ 2 java unit-testing spring-mvc mockito

我正在 Spring Mvc 上使用 Mockito 进行 JUnit 测试。测试使用 @InjectMock 和 @Mock 以及when(method(..)).thenReturn(X)。问题是如何@Mock @Inject 实例中的方法?

我尝试创建两个实例,例如 @InjectMocks Foo fooInstance 和 @Mock Foo fooInstanceMock;我的思维方式是区分注入什么实例和模拟什么。我还尝试将 Spy 与 InjectMocks 一起使用,但它返回异常。

实际类语法-

class Foo {
    public X(..) {
        ...
        Y(...); // method call to Y
        ...
    }

    public Y(..) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

测试语法 -

public class FooTest {
    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    @InjectMocks
    Foo fooInstance;

    @Mock
    Foo fooInstanceMock;

    @Test
    public void xTest{
        when(fooInstanceMock.Y(..)).thenReturn(true);
        Boolean result = fooInstance.X(25);
        Assert.assertTrue(result == true)
    }
}
Run Code Online (Sandbox Code Playgroud)

我除了返回 true 时输出为 true,但因为它认为它是一个jectMock 并且它进入实现。

Mur*_*nik 5

@InjectMocks用于使用此注释将您在测试中定义的模拟注入到非模拟实例中。

在您的用例中,看起来您正在尝试做一些有点不同的事情 - 您想要一个真正的实例,具有 的Foo实际实现x,但要模拟 的实现y,这x会调用。这可以通过部分模拟来完成,或者用 Mockito 的术语来说,就是监视:

public class FooTest{

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    // Default constructor is used to create a real Foo instance.
    // In the test's body, though, we'll override the behavior of SOME of the methods
    @Spy
    Foo fooInstance;

    @Test
    public void xTest {
        doReturn(true).when(fooInstance).y(/* arguments, presumably 25 */);
        Boolean result = fooInstance.x(25);
        Assert.assertTrue(result);
    }
}
Run Code Online (Sandbox Code Playgroud)