单元测试类由依赖注入Spring bean的方面编织

时间:2013-07-12 17:25:11

标签: java spring unit-testing aop aspectj

因为Spring驱动的AspectJ LTW无法编译在Spring初始化之前加载的类,所以我将Spring项目转换为纯Aspectj LTW(使用AspectJ weaver java代理)。

然而,这在我们的单元测试中附带启用AOP,因为我需要将AspectJ的代理添加到Maven Surefire插件argLine参数和我团队的IDE(IntelliJ IDEA)中的默认TestNG配置。

如果我们的Aspects不依赖于Spring,这不会成为问题,但是其中一些实际上需要通过@Resource表示法将Spring bean注入其字段中。由于Spring未在单元测试期间启动,因此该字段将为null并导致NullPointerExceptions。

即使我可以在构建过程中配置Surefire插件的两个独立执行:一个使用代理,另一个没有代理;这个解决方案将变得不切实际,因为每个开发人员仍然需要更改IDE的单元测试测试配置与实际需要AOP并启动Spring的其他测试,以进行每个独立的测试执行(即在Maven构建过程之外)。

解决这个问题的最佳方法是什么?有没有办法在保持java代理配置完整的同时禁用AspectJ的LTW?或者可能是另一种更灵活的方式来配置没有Spring驱动的AspectJ LTW问题的AspectJ的LTW?

1 个答案:

答案 0 :(得分:3)

我们可以争论是否一个好的设计决策让纯粹的AspectJ方面依赖于Spring魔法,或者它是否可以选择将Spring bean的模型注入方面。实际上,如果需要这样的框架,单元测试不是单元测试。方面也是如此。

无论如何,这是一个廉价的解决方案:使用if() pointcuts获取所有相关建议,并使它们取决于您是否处于测试模式。性能开销通常很小,不用担心。在你说它过于昂贵之前试一试。

也可以,但更昂贵的是通过cflow()cflowbelow()确定测试类是否在当前拦截的连接点的控制流中。在这种情况下我不推荐它。

第三个选项可能是在测试模式下将另一个 META-INF / aop.xml 添加到类路径中,该模式包含一个全局 exclude 语句,不包括编织中的所有类。 AspectJ documentation解释了如何在逻辑上合并多个 aop.xml 。可能这个选项是最好的,因为它不需要你改变你的方面。我没试过,但是如果你遇到任何困难我会想给我一个标志。