当切换到Kotlin时,静态方法会被移动到一个伴随对象中.然而,没有明显的方法来单元测试其他称为"静态方法"的方法.

在Java中,我们可以使用PowerMockito的MockStatic(SomeClass.class)来验证在测试的方法中调用了静态方法.PowerMock在Kotlin 失go 了魔力.

为了进行测试,我创建了以下类.

public class DummyJava {
    static public Void staticMechod(){
          System.out.print("Dummy method is called");
          return null;
     }
}

class DummyCompanion {
    companion object {
        fun someCompanionMethod(){
            System.out.printf("companion method is called\n")
        }
    }
}

现在还有一个叫做DummyCompanion.someCompanion的类

public class DummyWrapper {
    public void callAStaticMethod(){
        DummyJava.staticMechod();
    }

    public void callCompanionMethod(){
        DummyCompanion.Companion.someCompanionMethod();
    }
}

为了单元测试callAStaticMethod(),我们使用了以下方法

@RunWith(PowerMockRunner.class)
@PrepareForTest({DummyJava.class, DummyCompanion.Companion.class})
public class staticClassTest {
    //This case works
    @Test 
    public void testForStaticMethod() {
        PowerMockito.mockStatic(DummyJava.class);   
        DummyWrapper testObject = new DummyWrapper();

        Mockito.when(DummyJava.staticMechod()).thenCallRealMethod();

        testObject.callAStaticMethod();

        PowerMockito.verifyStatic(Dummy.class);
        DummyJava.staticMechod();
    }

    //This case doesn't work. It always passes.
    @Test
    public void testForCompanionMethod() {
        PowerMockito.mockStatic(DummyCompanion.Companion.class);
        DummyWrapper testObject = new DummyWrapper();
        testObject.callCompanionMethod();
PowerMockito.verifyStatic(DummyCompanion.Companion.class,Mockito.times(1));
        DummyCompanion.Companion.someCompanionMethod();
}

我的问题是如何验证同伴方法是否被调用.

推荐答案

Solution 1 : add a caller function in the calling class

public class DummyWrapper {
val foo get() = DummyCompanion.Companion

public void callAStaticMethod(){
    foo.staticMechod();
}

public void callCompanionMethod(){
    foo.someCompanionMethod();
}
}

In the test class, we can use Mockito to provide a stub for the get() function and verified it is called.

@Test
fun testCase{
....
val mockCompanionObj: DummyCompanion.Companion = mock()
val wrapper = DummyWrapper()

whenever(wrapper.foo).thenReturn(mockCompanionObj)
wrapper.callCompanionMethod()
verify(mockCompanionObj).someCompanionMethod()
....
}

Solution 2: using Mockk Mocking companion object in Mockk is easy. There is no need to insert a test interfacing object in the source code.

 @Test
 fun testCompanionObject() {
    //Mock the companion object
    mockkObject(DummyCompanion.Companion)

    //define the stubbing bechavior of a companion object method
    every { DummyCompanion.Companion.companionMethod() } answers { stubMethod() }

    val testObject = DummyWrapper()

    //Call a method that calls the companion object method
    //You can verify stubMethod() is called
    testObject.callCompanionMethod()

    verify(exactly = 1) { DummyCompanion.someCompanionMethod() }
}

For details see Mockk

Kotlin相关问答推荐

如何在 Big Data 中使用Inc过滤器?

调用即发即忘方法--哪个作用域?

Regex(Kotlin)仅匹配句子末尾的句号,而忽略中间的句号,如缩写

如何接受任何派生类KClass

如何在Android应用判断上运行多个查询

在构造函数中创建内部类实例时,只能使用包含类的接收器调用内部类的构造函数

为何Kotlin标准库中的AND和OR函数不能像&&和||一样进行短路运算?

Kotlin SIZE_BYTES

有什么方法可以要求在 kotlin 中的类型参数上进行注释?

使用启动或使用 coroutineScope 启动协程之间的区别

使用事务时未调用 Kafka ConsumerInterceptor onCommit

使用纯 Kotlin 函数作为 Junit5 方法源

什么是 .kotlin_builtins 文件,我可以从我的 uberjars 中省略它们吗?

Kotlin 静态函数:伴生对象,@JvmStatic @JvmField

Kotlin boxed Int 不一样

如何在MVVM架构中观察RecyclerView适配器中的LiveData?

取消信号上的kotlin流量采集

Kotlin 中的内联构造函数是什么?

Kotlin 的类型具体化使哪些在 Java 或 Scala 中无法实现的成为可能?

重复构建失败To use Coroutine features, you must add `ktx`......