在集成测试中,我的@afterreturn
建议被错误执行,而在测试中我模拟它以抛出TimeoutException,并且传递给方面的参数为null。
我的建议是:
@AfterReturning("execution(* xxxxxx" +
"OrderKafkaProducerService.sendOrderPaidMessage(..)) && " +
"args(order)")
public void orderComplete(CheckoutOrder order) { // order is null when debugging
metricService.orderPaidKafkaSent();
log.trace("Counter inc: order paid kafka"); // this line of log is shown in console
metricService.orderCompleted();
log.trace("Order complete! {}", order.getId()); // this line is not, because NPE
}
我的测试:
// mocking
doThrow(new ServiceException(new TimeoutException("A timeout occurred"), FAILED_PRODUCING_ORDER_MESSAGE))
.when(orderKafkaProducerService).sendOrderPaidMessage(any()); // this is where advice is executed, which is wrong
...
// when
(API call with RestAssured, launch a real HTTP call to endpoint; service is called during this process)
// then
verify(orderKafkaProducerService).sendOrderPaidMessage(any(CheckoutOrder.class)); // it should be called
verify(metricService, never()).orderCompleted(); // but we are throwing, not returning, we should not see this advice executed
由于NPE(订单为空),此测试失败。
在调试中,我发现当我进行模拟时,我已经执行了建议,此时,any()
还没有值,为空,所以NPE。但我不认为这些建议应该在嘲笑的时候执行。测试时如何避免这种情况??这对我来说太荒谬了。
目前Spring测试支持没有显式处理注入的mock或间谍(这是通过Mockito的代理子类)可能实际上是稍后的AOP目标(即代理并因此通过CGLIB再次子类化)的情况。
关于Spring、Spring Boot和Mockito,有几个与此主题相关的错误通知单。还没有人对此采取任何行动。我确实理解为什么Mockito维护人员不将特定于Spring的内容包含到他们的代码库中,但我不理解为什么Spring人员不改进他们的测试工具。
实际上,当调试失败的测试并检查kafkaService
时,您会发现以下事实:
kafkaService.getClass()
iscom.example.template.services.KafkaService$MockitoMock92961867$$EnhancerBySpringCGLIB$$8fc4fe95
kafkaService.getClass(). getSuperclass()
iscom.example.template.services.KafkaService$MockitoMock92961867$
kafkaService.getClass(). getSuperclass(). getSuperclass()
是类com.example.template.services.KafkaService换句话说:
kafkaService
是一个CGLIB Spring AOP代理。此外,更改包装顺序以使Mockito spy成为最外层的对象将不起作用,因为CGLIB故意使其覆盖方法成为最终方法,即不能再次扩展和覆盖它们。如果Mockito也有同样的限制,那么分层包装就根本不起作用。
不管怎样,你能做什么?
在您的情况下,后一种解决方案如下所示:
@Test
void shouldCompleteHappyPath() {
// fetch spy bean by unwrapping the AOP proxy, if any
KafkaService kafkaServiceSpy = AopTestUtils.getTargetObject(kafkaService);
// given mocked
doNothing().when(kafkaServiceSpy).send(ArgumentMatchers.any());
// when (real request)
testClient.create().expectStatus().isOk();
// then
verify(kafkaServiceSpy).send(ArgumentMatchers.any());
verify(metricService).incKafka();
}
这样做的效果是,当(kafkaServiceSpy)时。发送(ArgumentMatchers.any())不再触发方面建议,因为kafkaServiceSpy
不再是AOP代理。不过,自动连接的beankafkaService
仍然是,因此AOP如预期的那样被触发,但在记录模拟交互时不再不受欢迎地被触发。
实际上,对于验证,您甚至可以使用kafkaService
来代替间谍,并且只有在记录您以后想要验证的交互时才打开间谍:
@Test
void shouldCompleteHappyPath() {
// given mocked
doNothing()
.when(
// fetch spy bean by unwrapping the AOP proxy, if any
AopTestUtils.<KafkaService>getTargetObject(kafkaService)
)
.send(ArgumentMatchers.any());
// when(real request)
testClient.create().expectStatus().isOk();
// then
verify(kafkaService).send(ArgumentMatchers.any());
verify(metricService).incKafka();
}
附言:如果没有你的MCVE,我将永远无法调试它,并找出到底发生了什么。这再次证明,提出包括MCVE在内的问题是你能为自己做的最好的事情,因为它可以帮助你获得问题的答案,否则这些问题可能仍然没有答案。
更新:在我在类似的闭题Spring Boot#6871中提到这个问题后,一位维护人员自己创建了Spring Boot#22281,专门解决了您的问题。你可能想看看新问题,看看是否/何时可以解决。
当我使用Maven执行mvn将文件复制到远程服务器时。 然而,我得到下面的错误信息。我该怎么解决这个问题? 我正在遵循一个例子,如帖子所示https://jarirajari.wordpress.com/2014/06/11/copy-files-and-execute-command-on-a-remote-host-with-maven-antrun-plugin-without-ant-us
问题内容: 从终端以下作品没问题 其中包含一些文件(例如,file1,file2和file3)的目录在哪里。 但是,在Java中使用以下命令时出现错误 错误是 我相信我正确地转义了字符。我尝试了几种不同的格式,但无法正常使用。 UPDATE @jtahlborn完美地回答了这个问题。但是命令现在已经稍作更改,以在计算md5sum之前对目录中的每个文件进行排序,如下所示(我已经接受了原始问题的出色答
我有一个视图,它具有激活viewpager的表格布局,当查看页面时,它工作正常,但如果我单击该视图上的某个项目,然后返回到过去的屏幕,我会得到: Java.Lang.IllegalStateException:FragmentManager已经在执行事务。 不确定这是否有所不同,但当我离开这个视图时,我从一个片段变成了一个活动。
我看过几篇关于这个主题的帖子(post1,post2,post3)。在所有这些问题中,解决方案看起来都很容易,但我无法得到返回值的值。 这是我到目前为止所尝试的: 备选办法1: 备选案文3: 结果:原因,如果还注意到 创建到Java代码中的查询如下所示: 和连接字符串:
问题内容: 堆栈跟踪: 引用此代码http://pastebin.com/B9V6yvFu 奇怪的是,在我的LG4X上它可以正常工作,但是在我的三星s2上它会抛出上述错误。有什么想法怎么了? 问题答案: 因为在现有的消化周期内进行调用,所以收到此错误。 最大的问题是:您为什么打电话?除非您是从非Angular事件进行接口的,否则您根本不需要调用。通常的存在意味着我做错了事(除非,再次,$ appl
我面临这个运行时错误。它说: 错误:任务“:app:dexDebug”的执行失败。 com.android.ide.common.process.ProcessExcture:org.gradle.process.internal.ExecExc0019:进程'命令'/usr/lib/jvm/java-8-oracle/bin/java"完成非零退出值2 这是我的身材。渐变脚本: 请帮帮我。谢谢!