Ani*_*udh 5 testing junit android mockito kotlin
我正在尝试使用 Mockito 编写单元测试。我有一个类需要进行如下测试-
open class Employee {
fun setDetails(name: String, age: Int) {
setName(name)
setAge(age)
}
fun setName(name: String) { }
fun setAge(age: Int) { }
}
Run Code Online (Sandbox Code Playgroud)
下面是我的测试课
class EmployeeTest {
@Mock
lateinit var emp: Employee
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
}
@Test
fun testDetail() {
emp.setDetails("Henry", 23)
verify(emp, times(1)).setAge(23)
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的问题
当我做 -
verify(emp, times(1)).setAge(23)
Run Code Online (Sandbox Code Playgroud)
这给了我成功,因为 setAge 在 Employee.kt 的 setDetails() 中被调用一次。所以这对我来说很好用
但是,当我这样做时——
verify(emp, never()).setAge(23)
Run Code Online (Sandbox Code Playgroud)
即使在 setDetails() 中调用该方法,这仍然使我成功。这个测试用例不应该失败吗?
请帮助我理解这一点。我一直无法弄清楚为什么会发生这种情况。
编辑 这对我有用,我使用间谍而不是模拟。但是,我还必须在 Kotlin 中将这些方法声明为 open。
正如 @kcoppock 所提到的,您的问题包括对模拟的不当使用。您应该使用模拟来消除依赖关系,以控制它们的行为。
在您的情况下,被测试的单元是Employee类及其关联的方法。一般来说,您不想模拟被测试的单元,因为您想(从单元测试中)知道您的类是否按其应有的方式运行。为了实现这一点,您需要使用 的真实实例Employee,而不是模拟实例。
如果您坚持verify在Employee实例上使用,您可以创建一个spy.
@Test
fun setDetails_adjustsAge() {
val employee = spy(Employee())
employee.setDetails("Henry", 23)
assertEquals(23, employee.age)
verify(emp, times(1)).setAge(23)
}
Run Code Online (Sandbox Code Playgroud)
以下是一些供进一步阅读的参考资料:
Mockito关于间谍的官方文档: http://static.javadoc.io/org.mockito/mockito-core/2.24.0/org/mockito/Mockito.html#13
如何使用教程Mockito.spy
https://www.baeldung.com/mockito-spy
模拟和间谍之间的区别:https://www.toptal.com/java/a-guide-to-everyday-mockito
所以你的问题是你实际上不想使用模拟。当您使用模拟时,您需要为在该实例上调用的任何方法定义行为。因此,当您调用 时emp.setDetails("Henry", 23),该方法没有实现,因此什么也没有发生。类中定义的行为Employee将不会被使用,因为它emp只是一个Employee没有定义任何行为的假实例。
对于您的测试场景,您应该更喜欢使用真实实例,并验证最终结果而不是内部行为。例如:
@Test
fun setDetails_adjustsAge() {
val employee = Employee()
employee.setDetails("Henry", 23)
assertEquals(23, employee.age)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29545 次 |
| 最近记录: |