1. 简介
Kotlin 与 Java 高度兼容,这意味着我们可以在 Kotlin 项目中无缝使用大量现成的 Java 库。
本文将介绍如何在 Kotlin 中使用 Mockito 进行 mock 操作。如果你对 Mockito 不太熟悉,可以先阅读我们之前的文章:Mockito 注解详解。
2. 环境搭建
首先,创建一个 Maven 项目,并在 pom.xml
中添加 JUnit 和 Mockito 的依赖:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
别忘了告诉 Maven 项目中使用了 Kotlin,需要配置 Kotlin 插件。具体配置方式可参考 Kotlin 官方文档。
3. 在 Kotlin 中使用 Mockito
假设我们有一个类 LendBookManager
需要测试,它依赖一个尚未实现的 BookService
接口:
interface BookService {
fun inStock(bookId: Int): Boolean
fun lend(bookId: Int, memberId: Int)
}
LendBookManager
通过构造函数注入了 BookService
,并在 checkout
方法中使用了两次:
class LendBookManager(val bookService: BookService) {
fun checkout(bookId: Int, memberId: Int) {
if (bookService.inStock(bookId)) {
bookService.lend(bookId, memberId)
} else {
throw IllegalStateException("Book is not available")
}
}
}
如果我们不使用 mock,很难对这个方法进行单元测试。Mockito 就派上用场了。
我们可以轻松创建一个 BookService
的 mock 实例,并指定其行为:
val mockBookService = Mockito.mock(BookService::class.java)
Mockito.`when`(mockBookService.inStock(100)).thenReturn(true)
⚠️注意:when
是 Kotlin 的保留关键字,所以调用 Mockito 的 when()
方法时需要用反引号包裹。
接下来,将 mock 实例传入 LendBookManager
并调用测试方法:
val manager = LendBookManager(mockBookService)
manager.checkout(100, 1)
Mockito.verify(mockBookService).lend(100, 1)
还可以测试书籍不在库存时抛出异常的情况:
@Test(expected = IllegalStateException::class)
fun whenBookIsNotAvailable_thenAnExceptionIsThrown() {
val mockBookService = Mockito.mock(BookService::class.java)
Mockito.`when`(mockBookService.inStock(100)).thenReturn(false)
val manager = LendBookManager(mockBookService)
manager.checkout(100, 1)
}
4. 使用 mockito-kotlin 提升可读性
为了让代码更符合 Kotlin 的风格,可以使用 mockito-kotlin 这个开源库,它对 Mockito 做了 Kotlin 友好的封装:
✅ 示例代码如下:
@Test
fun whenBookIsAvailable_thenLendMethodIsCalled() {
val mockBookService: BookService = mock()
whenever(mockBookService.inStock(100)).thenReturn(true)
val manager = LendBookManager(mockBookService)
manager.checkout(100, 1)
verify(mockBookService).lend(100, 1)
}
这个库的优势在于:
- ✅ 提供
mock()
方法,支持类型推断,无需传参 - ✅ 使用
whenever()
替代 Mockito 的when()
,无需使用反引号 - ✅ 语法更简洁、更符合 Kotlin 风格
更多用法可以查看 mockito-kotlin Wiki。
5. 小结
本文介绍了如何在 Kotlin 项目中集成 Mockito,并通过 mock 对象进行单元测试。还推荐了一个非常实用的扩展库 mockito-kotlin
来提升代码的可读性和开发效率。
如果你希望查看完整源码,欢迎访问我们的 GitHub 仓库。