android - Kotlin - Mockito 验证方法调用

标签 android testing junit kotlin mockito

我正在尝试使用 Mockito 编写单元测试。我有一个类需要像下面这样测试-

open class Employee {
  fun setDetails(name: String, age: Int) {
    setName(name)
    setAge(age)
  }

  fun setName(name: String) { }

  fun setAge(age: Int) { }
}

下面是我的测试类

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)
  }

}

这是我的问题

当我做的时候-

verify(emp, times(1)).setAge(23)

这让我成功了,因为在 Employee.kt 的 setDetails() 中调用了一次 setAge。所以这对我来说很好

但是,当我这样做时-

verify(emp, never()).setAge(23)

即使在 setDetails() 中调用了该方法,这仍然使我成功。这个测试用例不应该失败吗?

请帮助我理解这一点。我一直无法弄清楚为什么会这样。

编辑 这是对我有用的 我用了一个 spy 而不是一个模拟。但是,我还必须在 Kotlin 中声明这些方法是开放的。

最佳答案

如@kcoppock 所述,您的问题包括对模拟的不当使用。您应该使用模拟来消除依赖关系以控制它们的行为。

在您的例子中,被测单元是 Employee 类及其相关方法。通常,您不想模拟被测单元,因为您想知道(从您的单元测试中)您的类是否按应有的方式运行。为此,您需要使用 Employee 的真实实例,而不是模拟。

如果您坚持在Employee 实例上使用verify,您可以创建一个spy

@Test
fun setDetails_adjustsAge() {
  val employee = spy(Employee())
  employee.setDetails("Henry", 23)

  assertEquals(23, employee.age)
  verify(emp, times(1)).setAge(23)
}

这里有一些供进一步阅读的引用资料:

  1. 关于 spy 的 Mockito 官方文档: http://static.javadoc.io/org.mockito/mockito-core/2.24.0/org/mockito/Mockito.html#13

  2. 关于如何使用 Mockito.spy 的教程 https://www.baeldung.com/mockito-spy

  3. mock 和 spy 的区别:https://www.toptal.com/java/a-guide-to-everyday-mockito

关于android - Kotlin - Mockito 验证方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54673354/

相关文章:

android - Google Glass GDK - 何时使用 Activity 与卡片?

android - 更改 AndroidTest 运行程序的任务

java - 从 jython 调用具有可变长度参数(varags)的 Java 方法

java - 为什么使用 junit-jupiter(聚合器)执行测试而不使用单独的依赖项?

java - 如何计算购物车中的总价?

android - 在 Activity 和 ListActivity 中共享相同的代码

junit - Jacoco Sling Junit 集成 - 测试执行

xml - 有没有办法以 junit.xml 格式生成 Jest/Istanbul 覆盖率报告

android - 获取 TableLayout 中的所有 TableRow

testing - 这个 rspec 辅助测试我做错了什么?