使用MockK模拟构造对象方法返回值报错:如何构建mockkConstructor?
MockK构造函数模拟异常问题解决方法
错误含义
这个异常明确说明:使用anyConstructed<T>()或constructedWith<T>(...)之前,必须先初始化并启用针对T类的构造函数Mock。MockK需要先明确要拦截哪个类的构造行为,才能对后续通过构造函数创建的该类实例,进行方法返回值的模拟配置。
构建并使用mockkConstructor<FooMaker>的步骤
1. 初始化构造函数Mock
在测试的初始化阶段(比如JUnit的@BeforeEach/@Before方法,或测试方法开头),调用mockkConstructor方法指定要Mock的类:
mockkConstructor(FooMaker::class)
如果希望未指定的方法自动返回默认值(避免每个方法都手动模拟),可以启用放松模式:
mockkConstructor(FooMaker::class, relaxed = true)
2. 配置方法返回值模拟
完成初始化后,就能正常使用anyConstructed<FooMaker>()配置所有通过构造函数创建的FooMaker实例的方法行为,也就是你原来的代码:
every { anyConstructed<FooMaker>().execute(fooId) } returns testFoo
3. 清理构造函数Mock
测试结束后,需要清理构造函数Mock,避免影响其他测试用例,放在JUnit的@AfterEach/@After方法中:
unmockkConstructor(FooMaker::class)
完整示例代码
import io.mockk.every import io.mockk.mockkConstructor import io.mockk.unmockkConstructor import org.junit.AfterEach import org.junit.BeforeEach import org.junit.Test import kotlin.test.assertEquals class FooMakerTest { private val testFooId = "test-foo-id" private val expectedFoo = Foo("test-foo-content") @BeforeEach fun setupMock() { // 初始化FooMaker的构造函数Mock mockkConstructor(FooMaker::class) } @AfterEach fun teardownMock() { // 清理构造函数Mock unmockkConstructor(FooMaker::class) } @Test fun `execute method returns expected Foo`() { // 配置方法返回值 every { anyConstructed<FooMaker>().execute(testFooId) } returns expectedFoo // 创建FooMaker实例(此时实例是MockK拦截的构造对象) val fooMaker = FooMaker() val actualFoo = fooMaker.execute(testFooId) // 断言结果 assertEquals(expectedFoo, actualFoo) } }
补充说明
官方文档的示例能正常运行,是因为文档省略了初始化mockkConstructor(MockCls::class)的代码,实际使用时必须先完成这一步,才能使用anyConstructed。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

