【发布时间】:2020-10-01 22:43:57
【问题描述】:
您好,我正在使用以下代码在我的 webflux 应用程序中使用 aop 打印日志,我在编写单元/集成测试时遇到问题?我们可以在这里验证日志交互吗?任何帮助将不胜感激
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Loggable {}
@Aspect
@Slf4j
public class LoggerAspect {
@Around("@annotation(Loggable)")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
var result = joinPoint.proceed();
if (result instanceof Mono) {
var monoResult = (Mono) result;
AtomicReference<String> traceId = new AtomicReference<>("");
return monoResult
.doOnSuccess(o -> {
var response = "";
if (Objects.nonNull(o)) {
response = o.toString();
}
log.info("Enter: {}.{}() with argument[s] = {}",
joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(),
joinPoint.getArgs());
log.info("Exit: {}.{}() had arguments = {}, with result = {}, Execution time = {} ms",
joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(),
joinPoint.getArgs()[0],
response, (System.currentTimeMillis() - start));
});
}
}
}
测试失败。 不知何故,当我调试指针没有进入 doOnNext 方法时。而且我不确定如何在上面的 Logging 方面断言日志交互。在 Junit5 中,我知道我可以为每个方法使用 mockito 并返回一些东西,但是我如何在 spock 中重新返回.
class LogAspectTest extends Specification {
private static final String MOCK_METHOD_LOG_VALUE = "mockMethodLogValue"
private Logger log = Mock()
private ProceedingJoinPoint mockJoinPoint = Mock()
private static Mono<String> methodReturn = Mono.just(["Data", "Data"])
private LogAspect logAspect = new LogAspect(log)
@Unroll
def 'logAround verify log interaction'() {
given:
mockJoinPoint.proceed() == Mono.just("Hello")
final Method method = TestClass.class.getMethod("mockMethod")
when:
logAspect.logAround(mockJoinPoint)
then:
interaction { mockJoinPointAndMethodSignatureInteractions(method, methodReturnToUse) }
where:
resultType | methodReturnToUse
'Mono' | methodReturn
}
private void mockJoinPointAndMethodSignatureInteractions(Method method, Publisher result) {
1 * mockJoinPoint.proceed() >> result
1 * log.info() >> ""
}
private static class TestClass {
@Loggable
Mono<String> mockMethod() { return Mono.just("data") }
}
}
是否建议为 @Loggable 注释编写集成测试,因为它只是记录不知道如何编写断言日志语句的集成测试
【问题讨论】:
-
能否请您展示您目前进行的测试并解释您遇到的问题?
-
将我的测试添加到问题中。
-
被测代码仍然缺失,名称
LoggerAspect与测试中使用的LogAspect不一样。在方面的建议方法的末尾也缺少return result;语句。如果结果不是Mono,您还必须返回一些内容。我认为在将代码发布到此处之前实际编译和运行代码总是一个好主意,因为自愿帮助您的人不想在重现实际问题之前首先弄清楚如何在结构上修复您的代码。 -
此外,没有导入和包名称,但我假设您的
@Slf4j注释来自 Lombok。 Lombok 创建的内容类似于private static final Logger log = LoggerFactory.getLogger(LogAspect.class);,因此您不能为该成员分配任何内容,因为它既是最终的又是私有的。此外,没有构造函数LogAspect(Logger logger)像您在测试中伪造使用它。所以这甚至不能编译。 -
我偶然发现了this article。也许您应该将其作为来源提及,而不是仅仅复制代码,假装它是您自己的。
标签: java spring-webflux spring-aop spock