【发布时间】:2019-02-12 09:59:09
【问题描述】:
所以我在我的项目中使用Spring=Retry 库并尝试为此运行一个测试用例。
我将服务 DCS 作为返回新对象的 bean 加载。
它的两个依赖项 SSService 和 AttributeService 也作为 bean 加载。但这两个是嘲笑。
当我的测试规范运行时,我可以在 DCS.execute 中看到模拟正常。但是像1 * SSService.read(_ as LComponent,_) >> mockSimpleSettingCommResult 这样的交互没有生效,导致空值而不是我希望它返回的值。
@ContextConfiguration(classes = [SpringRetryConfig])
class DCSISpec extends Specification {
@Autowired
DCS DCS
@Autowired
SSService sSService
@Autowired
AttributeService attributeService
def setup() {
// DCS.SSService = SSService
// DCS.attributeService = attributeService
}
def "execute failure"(){
setup:
DataCollectionDataSet mockDataCollectionDataSet = Mock(DataCollectionDataSet)
LComponent mockLComponent = Mock(LComponent)
SSCommResult mockSimpleSettingCommResult = Mock(SSCommResult)
ReflectionTestUtils.setField(DCS, "SSService", SSService)
ReflectionTestUtils.setField(DCS, "attributeService", attributeService)
when:
DCS.execute(mockLComponent, mockDataCollectionDataSet)
then:
1 * mockSimpleSettingCommResult.getDegreeOfSuccess() >> SSCommResult.DegreeOfSuccess.FAILURE
1 * mockDataCollectionDataSet.getNamespace() >> DCSNamespace.xyz
1 * mockDataCollectionDataSet.getDataElements() >> ["FOO": "BAR"]
1 * SSService.read(_ as LComponent,_) >> mockSimpleSettingCommResult
3 * DCS.execute(_ as LComponent, _ as DataCollectionDataSet)
}
@Configuration
@EnableRetry
public static class SpringRetryConfig {
@Bean
public SSService SSService() {
Mockito.mock(SSService)
}
@Bean
public AttributeService attributeService() {
Mockito.mock(AttributeService)
}
@Bean
public DCS DCS() {
return new DCS();
}
}
}
这是我尝试使用普通 Mockito 时遇到的异常,
java.lang.NullPointerException
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:41)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at com.lexmark.mps.cma.service.DataCollectionRetryTest.test_retry(DataCollectionRetryTest.groovy:70)
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:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
【问题讨论】:
-
你为什么要在
Mockitos 模拟SSService上配置 Spock 交互。它不是那样工作的。此外,你在那次互动中拼错了sSSservice(你有SSSservice) -
最后,您无法通过在真实对象(
3 * DCS.execute...)上配置交互来测试重试。只需模拟它,以便第一次调用导致重试并且最终调用成功。然后查看调用次数 -
@DmitryKhamitov 你能告诉我一个使用 spock 的春季重试测试的例子吗?我很难通过 Spock 进行重试测试。最重要的是,我们的项目使用了相当老的 Spock 0.7。
-
我知道已经有一个公认的答案,但问题是关于 Spock,所以我想知道如果你可以使用 Spock 模拟,你为什么要使用 Mockito。如果这是一个选项,您会对 Spock 解决方案感兴趣,还是只是从 Spock 迁移到 JUnit?
-
我明白你的意思。我还没有找到使用 Spock 的更好方法。但是,如果我能找到一个,我会自己添加一个新答案。现在我正在使用 JUNit4 和 Mockito 来做到这一点。是的,如果有 Spock 选项,我会接受!
标签: spring mocking spock spring-retry