java - Mockito:监视一个spring autowrite bean,它不起作用
问题描述
我想在间谍一个spring bean上模拟approveActivity方法。
但在这方面,它是行不通的。
spring 自动写入对象是成功的。
间谍对象是成功的。
模拟方法抛出异常。
在此处输入代码
我不知道为什么,请帮助我!
SpringFramework 3.X 和 Mockito 2.x 和 Junit 4.X。
public class ActivityBasicSmokeTest extends AbstractSmockMockito4SpringTest {
@Autowired
private ActivityReduceAPI activityReduceAPI;
@Test
public void testForApprovingActivityStatus() throws FileNotFoundException {
ActivityReduceAPI spyActivityReduceAPI = Mockito.spy(this.activityReduceAPI);
// stop auto audit
Mockito.doReturn(new ResultGeneralModel<>(true)).when(spyActivityReduceAPI)
.approveActivity("1", 2L); <---- this is throw Exception.
}
}
ActivityReduceAPIImpl.java
@Override
public ResultGeneralModel<Boolean> approveActivity(String token, Long id) {
try {
AccountResponse account = sessionContext.getAccountFromTairByToken(token);
ReduceActivityEntity activityEntity = activityService.get(id, account);
ActivityParamUtil.validBeforeModified(activityEntity, ActivityStatusEnum.CREATE);
Errors error = activityService.approveReduce(activityEntity, account);
if (null != error) {
return new ResultGeneralModel<>(error);
}
return new ResultGeneralModel<>(true);
} catch (TfavatarBusException e) {
return new ResultGeneralModel(ErrorUtil.getErrors(e));
}
}
org.mockito.exceptions.misusing.UnfinishedStubbingException:此处检测到未完成的存根:在 com.taobao.film.tfavatar.domain.reduce.ActivityBasicSmokeTest.testForApprovingActivityStatus(ActivityBasicSmokeTest.java:458)
例如 thenReturn() 可能会丢失。正确的存根示例:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
提示: 1. 缺少 thenReturn() 2. 您正在尝试存根不支持的最终方法 3:您正在存根在 'thenReturn' 指令完成之前内部另一个模拟的行为
at com.taobao.film.tfavatar.api.impl.ActivityReduceAPIImpl.approveActivity(ActivityReduceAPIImpl.java:192)
at com.taobao.film.tfavatar.api.impl.ActivityReduceAPIImpl$$FastClassBySpringCGLIB$$f237c997.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:701)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:93)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:633)
at com.taobao.film.tfavatar.api.impl.ActivityReduceAPIImpl$$EnhancerBySpringCGLIB$$4b39213a.approveActivity(<generated>)
at com.taobao.film.tfavatar.domain.reduce.ActivityBasicSmokeTest.testForApprovingActivityStatus(ActivityBasicSmokeTest.java:459)
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:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
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:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
解决方案
Edit4:最后在自己建立了一个spring 3项目之后,我可以验证cglib生成的方法确实是最终的。
打印出代理类的方法和它们的修饰符给了我这样的东西:
class test.ActivityReduceAPI$$EnhancerBySpringCGLIB$$747ceb58
methods:
...
approveActivity public final
...
CGLIB$approveActivity$1 final
...
使用 CglibHelper 类(在此处找到 https://www.thekua.com/atwork/2011/06/finding-real-object-under-spring-proxies/)我能够从代理中提取真实对象。有了这个,测试正在运行。
@Test
public void testForApprovingActivityStatus() {
ActivityReduceAPI spyActivityReduceAPI = Mockito.spy((ActivityReduceAPI) new CglibHelper(activityReduceAPI).getTargetObject());
Mockito.doReturn(new ResultGeneralModel<Boolean>(true)).when(spyActivityReduceAPI)
.approveActivity("1", 2L);
Assert.assertTrue(spyActivityReduceAPI.test("1", 2L));
}
推荐阅读
- xslt - 如何使用 XSLT 转换来转换 Soap 对象数据
- python - Django 包含从 AbstractUser 到注册表单的字段
- bitbucket - 在 Bitbucket 管道中定义多个环境构建
- python - 如何修复我的代码:ValueError:int() 的无效文字,基数为 10:''
- edge-detection - 计算边缘占据的图像面积 - 精明的边缘检测
- botframework - 如何在 Microsoft Bot Composer 中访问对话框堆栈
- laravel - Laravel - 如何使用 Laravel Maatwebsites 导入两 (2) 个表
- c++ - 在 Windows 7 上安装 Tesseract for C++
- javascript - 当用户使用 Javascrip 上下滚动时更改图像
- javascript - sapui5 - 为 smartTable 实现自定义排序器