[英]Mockk set private properties of collection in Kotlin
在 Mockk 中访问私有变量时,无法设置私有属性的值。
我们有 CustomerImpl class,它有 1 个名为customerData
的私有属性。
我们希望在不调用updateCache()
方法的情况下从我们的测试用例中设置私有属性customerData
中的数据。
我们正在使用Mockk 1.10.6
CustomerImpl Class
class CustomerImpl {
private var customerData : MutableList<CustomerModel> = mutableListOf()
private fun updateCache() {
... here customerData is updated.
}
fun clearCache() {
if(customerData.isNotEmpty())
customerData.clear()
}
}
测试 Class
class CustomerImplTest {
private lateinit var customerImpl: CustomerImpl
@Before
fun setUp() {
MockKAnnotations.init(this)
customerImpl = spyk(CustomerImpl(), recordPrivateCalls = true)
}
@Test
fun clearCacheTest() {
val customer = listOf(CustomerModel(id = "3", name = "John"))
every { customerImpl setProperty "customer" value customer } just Runs
customerImpl.clearCache()
}
}
当我们尝试运行这个测试用例时,它给了我们以下错误。
例外
io.mockk.MockKException: Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock
at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14)
at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8)
at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47)
at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:60)
at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:30)
at io.mockk.MockKDsl.internalEvery(API.kt:92)
at io.mockk.MockKKt.every(MockK.kt:98)
at com.xyz.impl.CustomerImplTest.clearCacheTest(CustomerImplTest.kt:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
我们只在 Mockk 中寻找解决方案。
如果您希望能够使用您的 class 测试所有场景,您应该注入所有依赖项而不是在内部创建对象。
正如已经建议的那样,您需要将列表作为构造函数参数传递。
class CustomerImpl(
private var customerData : MutableList<CustomerModel> = mutableListOf()
) {
private fun updateCache() {
// Here customerData is updated.
}
fun clearCache() {
if(customerData.isNotEmpty())
customerData.clear()
}
}
class 的真正消费者将以相同的方式工作,但您将能够注入依赖项。 如果您担心以某种方式暴露customerData
数据,请考虑您可以/应该有一种工厂来构建实例而不知道具体的 class。例如:
interface Customer {
fun clearCache()
companion object {
fun newInstance(): Customer = CustomerImpl()
}
}
class CustomerImpl(
private var customerData : List<CustomerModel> = mutableListOf()
): Customer {
private fun updateCache() {
// Here customerData is updated.
}
override fun clearCache() {
if(customerData.isNotEmpty())
(customerData as? MutableList)?.clear()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.