Java 单元测试编译时编织

Java 单元测试编译时编织,java,spring,junit,aspectj,aspectj-maven-plugin,Java,Spring,Junit,Aspectj,Aspectj Maven Plugin,在编译时,我使用。当我运行应用程序时,带有@Advice注释的类在第一次调用Advice之前被实例化。例如: @Aspect public class MyAdviceClass { public MyAdviceClass() { System.out.println("creating MyAdviceClass"); } @Around("execution(* *(..)) && @annotation(timed)")

在编译时,我使用。当我运行应用程序时,带有
@Advice
注释的类在第一次调用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
注释的方法,则在第一次调用该方法时将打印“creating MyAdviceClass”,并且每次都将打印“Timed annotation called”

我想通过模拟
MyAdviceClass
中的一些组件来单元测试通知的功能,但是不能这样做,因为
MyAdviceClass
是由AspectJ及时实例化的,而不是通过Springbeans实例化的


对于这样的单元测试,什么是最佳实践方法?

我已经找到了解决方案,并想将其发布给遇到这种情况的其他人。诀窍是在springbean定义中使用
factory method=“aspectOf”
。因此,使用上面的示例,我将把这一行添加到我的
applicationContext.xml

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

更多详细信息可用。

通常单元测试涉及模拟外部依赖项,但我看不到任何。我猜你想模拟一些外部依赖?还是要模拟该建议?使用其构造函数创建一个
MyAdviceClass
实例,对
ProceedingJoinPoint
Timed
使用模拟?Taylor,为了简单起见,我已经排除了它们@你是对的,我可以用这种方式测试
doBasicProfiling
方法,但我还想测试在执行带注释的方法时是否调用了通知。最简单的方法是模拟方面的外部性(某些服务/dao/它调用的任何东西),注入它,并验证它是否按预期调用是的,完全正确。不幸的是,由于AspectJ是在第一次需要时创建实例,而不是通过Springbean创建实例,因此我找不到它为了进行注入而创建的实例。
@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
    }
}