首页 文章

如何在Mockito中验证在测试期间调用了另一种SUT公共方法

提问于
浏览
0

我知道重复,没有回答关于那里的实际问题 .

How to verify if method is called on System under test (not a mock)

我有一节课:

class A {

    public long a() {
        if(something) {
            return quicklyCalculatedResult
        } else {
            return b() run on separate thread, with this one blocked
        }
    }

    public long b() {} //doStuffOnCurrentThread;

}

我有一套完整的b()测试,可以完成繁重的工作 . 不幸的是,我必须像一个()(遗留代码)做一个丑陋的想法,我不想复制所有的测试 . 方法b() . 此外,这两者都需要公开 .

我想验证在某些情况下a()调用b(),但我不能这样做,因为测试类不是模拟 . 我需要一种方法来验证方法是否在真实对象上调用,而不仅仅是模拟 .

2 回答

  • 2

    Mockito和其他kotlin模拟库提供部分模拟或类似功能 . 您可以指定要调用的实际方法,而其他方法仍然是存根:

    Mockito java示例:

    A classUnderTest = mock(A.class);
    when(classUnderTest.a()).thenCallRealMethod();
    
    classUnderTest.a();
    verify(classUnderTest).b()
    

    有关部分嘲笑,请参阅mockito Documentation . 不鼓励部分模拟,因为它不适合良好的OOP设计,但在您的情况下,它符合其预期目的,即测试困难的遗留代码 .

    Kotlin与香草Mockito的例子:

    val classUnderTest = mock(A::class.java)
    `when`(classUnderTest.a()).thenCallRealMethod()
    
    classUnderTest.a()
    verify(classUnderTest).b()
    

    mockito-kotlin提供的扩展程序允许您以更加科特林惯用的方式使用mockito . 不幸的是,似乎没有办法以kotlin习惯的方式进行部分 Mock ,但它可以在mockito-kotlin中实现,如下所示:

    val classUnderTest = mock<A>()
    doCallRealMethod().whenever(classUnderTest).a()
    
    classUnderTest.a()
    verify(classUnderTest).b()
    

    MockK,一个惯用的kotlin模拟库,允许使用spys这个功能 . 创建类的 spy 后,您可以选择存根方法:

    val classUnderTest = spyk<A>()
    every { classUnderTest.b() } returns 1L
    
    classUnderTest.a()
    verify { classUnderTest.b() }
    
  • 2

    您可以使用@SpyMockito.spy() 制作 A Spy . 这将允许您调用和测试 a() 方法逻辑,但也用不变量替换 b() . 这可以通过列表来说明:

    List list = new LinkedList();
    List spy = Mockito.spy(list);
    
    // Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
    when(spy.get(0)).thenReturn("foo");
    
    // You have to use doReturn() for stubbing
    doReturn("foo").when(spy).get(0);
    

相关问题