我很擅长为方面编写单元测试。在对单元测试方面进行了一些阅读之后,我得出结论,有两种类型的测试要写:测试方面的逻辑,并测试拦截(即,它是否正确拦截)。我对逻辑部分进行了单元测试。但是,我一直在努力为拦截部分进行测试。
我正在使用JUnit 4,JMockit和Guice(用于CDI和AOP)编写测试。
下面的类是我的方面,它记录了方法调用的执行时间。
class ExecutionTime implements MethodInterceptor {
private static final Logger logger = ...
public Object invoke(MethodInvocation invocation) throws Throwable {
final long start = System.nanoTime();
try {
return invocation.proceed();
} finally {
final long end = System.nanoTime();
logger.trace(...);
}
}
}
在Guice中,我创建了一个用于初始化注入器的Module
。代码如下。绑定表示@DoNotProfile
方面忽略任何未使用ExecutionTime
注释的类和方法。
class ProfilingModule extends AbstractModule {
public void configure() {
bindInterceptor(not(annotatedWith(DoNotProfile.class)),
not(annotatedWith(DoNotProfile.class)), new ExecutionTime());
}
}
接下来,我定义了一个测试类,我可以测试这些方法是否被正确拦截。其中一些方法使用@DoNotProfile
注释。
class TestClass {
public void methodA() {}
@DoNotProfile public void methodB() {}
...
}
最后,在我的测试类中,我的测试方法中包含以下代码。
@Test
public void test() throws Throwable {
Injector injector = Guice.createInjector(new ProfilingModule());
... // not sure what to do next
}
我不确定接下来该做什么。我尝试了以下内容。
invoke
类的ExecutionTime
方法。但是,我无法做到这一点。ExecutionTime
相同的绑定创建了一个测试拦截器,并使用了测试模块。也就是.createInjector(new TestModule())
。但我意识到这打败了这个测试的目的,即测试接线是否正常工作。感谢您对此事的任何见解和帮助。
答案 0 :(得分:1)
如果遇到这类问题,请退后一步再思考一下:我的应用程序的构建块是什么?然后将它们作为任意单位进行测试。
在您的情况下:" MethodInterceptor是否使用正确的值调用记录器"和"模块是否正确绑定了ExecutionListener"。我假设你已经完成了第一个。
对于第二个:覆盖单元测试中的模块以提供ExecutionListener的模拟,然后只需验证其"调用"根据注释的存在,方法被调用/不被调用。
由于MethodInterceptors只能绑定为具体实例,因此最简单的方法是为传递ExecutionListener实例的模块提供构造函数。然后,您可以使用新实例作为默认值,并在测试中传递模拟。