mockito mock一个被另一个方法调用的方法

xn1cxnb4  于 2023-10-18  发布在  其他
关注(0)|答案(3)|浏览(168)

我的课

class X {
    protected int a() { return 1; }
    protected int b() { return a(); }
}

我的测试代码

X x = mock(X.class)
when (x.a()).thenReturn(100);
// System.out.println(x.a());
assertEquals(100, x.b());

Assert失败,因为b()中的a()仍然返回1。如果我取消注解debug行,则打印100。但是Assert仍然失败,返回1。
我做错了什么?我期望x.a()在所有情况下都返回100,而不仅仅是在我直接调用它的时候。

f45qwnt8

f45qwnt81#

最佳实践表明,您要么完全模拟对象,要么根本不模拟对象。因此,Mockito嘲笑被嘲笑对象的每一个方法。如果你只想模拟一些方法,你必须告诉它你不想模拟哪些方法:

when (x.a()).thenReturn(100);
when (x.b()).thenCallRealMethod();

这称为部分模拟。在Javadoc的第16节中阅读更多信息。

6ju8rftf

6ju8rftf2#

Mockito必须配置为使用部分模拟方法。
这个类需要测试:

public class Something {

    protected int a() {
        return 1;
    }

    protected int b() {
        return a();
    }
}

解决方案A -使用mock()

class SomethingTest {

    @Test
    void mockTest() {
        var mock = mock(Something.class);

        when(mock.a()).thenReturn(100); // mocking method call a()
        when(mock.b()).thenCallRealMethod(); // call the real implementation
        assertEquals(100, mock.b());
        assertEquals(100, mock.a());
    }
}

解决方案B -使用spy()

间谍对象调用真实的方法,除非它们被存根化。

class SomethingTest {

    @Test
    void spyTest() {
        var spy = spy(Something.class);
        when(spy.a()).thenReturn(100);
        assertEquals(100, spy.b());
        assertEquals(100, spy.a());
    }
}
lf3rwulv

lf3rwulv3#

问题是您正在使用protected。试图像这样直接模拟受保护的方法是不可能的。将a()更改为public,它应该可以工作。

相关问题