【问题标题】:Unit testing compile-time weaving单元测试编译时编织
【发布时间】:2014-02-12 19:01:43
【问题描述】:

我在编译时使用aspectj maven plugin 来编织Aspects。当我运行应用程序时,带有@Advice 注释的类在第一次调用通知之前被实例化。例如:

@Aspect
public class MyAdviceClass {

    public MyAdviceClass() {
        System.out.println("creating MyAdviceClass");
    }

    @Around("execution(* *(..)) && @annotation(timed)")
    public Object doBasicProfiling(ProceedingJoinPoint pjp, Timed timed) throws Throwable {
        System.out.println("timed annotation called");
        return pjp.proceed();
    }
}

如果我有一个使用@Timed注解的方法,那么第一次调用该方法时将打印“正在创建的MyAdviceClass”,并且每次都会打印“调用的定时注解”。

我想通过模拟MyAdviceClass 中的一些组件来对建议的功能进行单元测试,但是不能这样做,因为MyAdviceClass 是由 AspectJ 及时实例化的,而不是通过 Spring Beans。

对此类进行单元测试的最佳实践方法是什么?

【问题讨论】:

  • 通常单元测试涉及模拟外部依赖项,但我没有看到任何。我猜你想模拟一些外部依赖项?或者你想嘲笑这个建议?
  • 使用其构造函数创建一个MyAdviceClass 实例,为ProceedingJoinPointTimed 使用模拟?
  • @Taylor,为简单起见,我已将它们排除在外。 @RC.,你是对的,我可以通过这种方式测试 doBasicProfiling 方法,但我还想测试在执行带注释的方法时是否调用了建议。
  • 最简单的方法是模拟切面的外部性(一些服务/dao/它调用的任何东西),注入它,并验证它是否按预期调用
  • 是的,完全正确。不幸的是,由于 AspectJ 是在第一次需要它时创建实例而不是通过 Spring Bean,所以我找不到它为进行注入而创建的实例。

标签: java spring junit aspectj aspectj-maven-plugin


【解决方案1】:

我找到了解决方案,并希望将其发布给遇到此问题的其他人。诀窍是在你的spring bean定义中使用factory-method="aspectOf"。因此,使用上面的示例,我会将这一行添加到我的applicationContext.xml

<bean class="com.my.package.MyAdviceClass" factory-method="aspectOf"/>

我的任何单元测试都应该是这样的:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml")
public class MyAdviceClassTest {
    @Autowired private MyAdviceClass advice;
    @Mock private MyExternalResource resource;

    @Before
    public void setUp() throws Exception {
        initMocks(this);
        advice.setResource(resource);
    }

    @Test
    public void featureTest() {
        // Perform testing
    }
}

更多详情请见here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多