【发布时间】:2018-02-17 07:55:49
【问题描述】:
问题
在@Test,我怎样才能同时实现;
- 从被测的 Kotlin 类中调用真实方法并
- 将内部调用存根到此类被测类中的其他方法。
场景
我正在使用以下库;
testCompile "com.nhaarman:mockito-kotlin:1.5.0"
testCompile "org.mockito:mockito-inline:2.12.0"
我也有一个简单的 kotlin 类
class MyClass() {
fun parentFunc() {
funA()
}
fun funA() {
//DOES SOMETHING WHICH I ASSUME IS IRRELEVANT FOR ANSWERING THE QUESTION
}
}
用间谍进行测试
@Test
fun myTest() {
val myClassSpy = spy(MyClass())
Mockito.doNothing().`when`(myClassSpy.funA())
//Mockito.doNothing().whenever(myClassSpy.funA()) also throws the same error
myClassSpy.parentFunc()
verify(myClassSpy, times(1)).funA()
}
哪个会引发错误,
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.nhaarman.mockito_kotlin.MockitoKt.doNothing(Mockito.kt:108)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
另一个测试用例;
@Test
fun myTest() {
val myClassSpy = Mockito.spy(MyClass())
myClassSpy.parentFunc()
verify(myClassSpy, times(1)).funA()
}
给出以下错误:
Wanted but not invoked:
myClass.funA();
However, there was exactly 1 interaction with this mock:
myClass.parentFunc();
此外,每当我尝试使用调试器调用 myClassSpy 方法或与之相关的东西时,它都会引发以下错误:
com.sun.jdi.InternalException : Unexpected JDWP Error: 41
我尝试过使用
Mockito.`when`(myClassSpy.funA()).then { }
Mockito.`when`(myClassSpy.funA()).thenAnswer { }
Mockito.`when`(myClassSpy.funA()).thenReturn(Unit)
使用模拟测试
在这种情况下模拟整个类不起作用,因为它是一个模拟并且不调用被测的真实方法:
@Test
fun myTest() {
val myMock: MyClass = mock()
myMock.parentFunc()
verify(myMock, times(1)).funA()
}
同样的错误:
Wanted but not invoked:
myClass.funA();
However, there was exactly 1 interaction with this mock:
myClass.parentFunc();
如果我进一步调用真正的方法,它也会显示相同的wanted but not invoked myClass.funA(); 错误:
@Test
fun myTest() {
val myMock: MyClass = mock()
Mockito.`when`(myMock.parentFunc()).thenCallRealMethod()
myMock.parentFunc()
verify(myMock, times(1)).funA()
}
我也尝试打开MyClass,但也出现了同样的错误。
因此,我如何对间谍的方法进行存根,以便当我测试来自此类间谍对象的方法时,它不会将调用传播到我不想进一步模拟的其他方法。
非常感谢任何帮助、建议、想法...以测试这些类型的方法。
【问题讨论】:
-
使用 spy 进行测试时,
when方法必须获取 spy 对象而不是其方法作为参数。你应该打电话给Mockito.doNothing().when(myClassSpy).funA()。
标签: android unit-testing kotlin mockito