Mockk 简介:它是什么以及为什么需要它
\n\nMockk 是一个用于在 Kotlin 编程语言中进行模拟(创建对象模拟)的现代库。它专门针对 Kotlin 的特性而设计:可空性、扩展函数、协程、伴生对象以及其他 Java 中不存在的功能。
\n\n为什么需要 Mockk 库? 在编写单元测试时,我们经常遇到被测类依赖于其他类、服务、数据库或外部 API 的情况。为了隔离被测代码,并使测试快速、可靠且独立于外部因素,我们创建“模拟对象”(mock objects)——这些对象是模拟真实依赖项行为的存根对象。
\n\nMockk 的主要功能:
\n- \n
- 为类、接口和对象创建模拟 \n
- 支持注解(@MockK, @RelaxedMockK, @SpyK) \n
- 支持协程(coEvery, coVerify) \n
- 模拟扩展函数 \n
- 模拟静态方法和伴生对象 \n
- 支持插槽(slot)和参数捕获 \n
- 支持部分模拟(spy) \n
安装 Mockk
\n\nMockk 通过 Maven Central 分发。要将其添加到项目中,请在 build.gradle.kts 文件中添加依赖项(适用于使用 Kotlin DSL 的 Gradle):
// build.gradle.kts\ndependencies {\n testImplementation("io.mockk:mockk:1.13.10")\n}\n\n对于使用 Groovy DSL 的 Gradle:
\n\n// build.gradle\ndependencies {\n testImplementation "io.mockk:mockk:1.13.10"\n}\n\n对于 Maven:
\n\n<dependency>\n <groupId>io.mockk</groupId>\n <artifactId>mockk</artifactId>\n <version>1.13.10</version>\n <scope>test</scope>\n</dependency>\n\n如果您使用协程,则无需额外添加任何内容——Mockk 内置了对协程的支持。
\n\n快速入门与代码示例
\n\n让我们看一个最简单的例子。假设我们有一个 UserService 服务,它依赖于 UserRepository 仓库:
// 用于测试的类\nclass UserRepository {\n fun findById(id: Long): String {\n // 实际实现会访问数据库\n return "Real User"\n }\n}\n\nclass UserService(private val repository: UserRepository) {\n fun getUserName(id: Long): String {\n val user = repository.findById(id)\n return if (user.isNotEmpty()) user else "Unknown"\n }\n}\n\n现在,我们使用 Mockk 编写一个测试:
\n\nimport io.mockk.every\nimport io.mockk.mockk\nimport io.mockk.verify\nimport org.junit.jupiter.api.Test\n\nclass UserServiceTest {\n\n @Test\n fun `getUserName should return user name from repository`() {\n // 1. 为仓库创建模拟对象\n val mockRepository = mockk<UserRepository>()\n \n // 2. 定义模拟对象的行为\n every { mockRepository.findById(1L) } returns "John Doe"\n \n // 3. 使用模拟对象创建被测对象\n val service = UserService(mockRepository)\n \n // 4. 调用被测方法\n val result = service.getUserName(1L)\n \n // 5. 验证结果\n assert(result == "John Doe")\n \n // 6. 验证该方法被恰好调用了 1 次\n verify(exactly = 1) { mockRepository.findById(1L) }\n }\n}\n\nMockk 的主要方法和函数
\n\n让我们看看库中的 10 个关键方法,并附有详细描述和示例。
\n\n1. mockk() — 创建模拟对象
\n功能: 为指定的类或接口创建一个模拟对象。默认情况下,模拟对象的所有方法返回默认值(null, 0, false),如果调用未定义行为的方法则会抛出异常。