Spring的单元测试@Around AOP方法

49

大多数Spring类都可以不需要进行Spring "stuff",就可以进行单元测试。

我也可以在不使用Spring的情况下对@Before通知方法进行单元测试:

示例代码:

@Before("execution(* run(..)) && " + "" +
          "target(target) && " +
        "args(name)")
public void logName(Object target, String name) {
    logger.info("{} - run: {}", target, name);
}

示例测试:

@Test
public void testLogName() {
    aspect.setLogger(mockLogger);
    aspect.logName(this,"Barry");
    assertTrue(mockLogger.hasLogged("TestAspect - run: Barry"));
}

然而,@Around增强处理的是一个ProceedingJoinPoint对象:

@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
   // start stopwatch
   Object retVal = pjp.proceed();
   // stop stopwatch
   return retVal;
 }

我不知道如何实例化一个ProceedingJoinPoint对象。在不启动整个Spring应用程序上下文的情况下,我该如何测试这个类?


你能提供完整的代码吗?展示一下你是如何实现@Before测试用例的?我需要帮助来实现它。 - kk.
1个回答

109

您可以通过编程创建代理来测试Spring Aspect:

MyInterface target = new MyClass();
AspectJProxyFactory factory = new AspectJProxyFactory(target);
MyAspect aspect = new MyAspect(arg);
factory.addAspect(aspect);
MyInterface proxy = factory.getProxy();

...然后您可以调用 proxy 的方法,并对 aspectproxytarget 进行断言。


1
非常感谢 - 最终我可以正确地测试那个东西了。你有任何想法为什么你必须以编程方式完成这个程序吗?我将MyAspect声明为一个bean,并在单元测试中加载此上下文,因此期望该方面被执行 - 但它只能按照你描述的方式工作... - Alexander Hansen
断言会是什么样子?你有一些例子吗? - mip
1
@mip 就像在普通的 jUnit 测试中所做的那样,你需要进行相同类型的断言;具体细节完全取决于你要测试的类应该执行什么操作。例如,如果该 Aspect 应该记录某些内容,则断言其 OutputStream 接收到了预期的字符。 - slim
1
@mip 你需要学习关于模拟的知识。Mockito 和 JMock 是两个选择。 - slim
@slim已经解决了,谢谢。混淆在于代理的工作方式。干杯。 - mip
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接