我有一个Spring MVC应用程序,在其中我使用Aspect来捕获所有控制器方法中的异常
@Component
@Aspect
public class ControllerExceptionAspect {
private Logger logger;
public ControllerExceptionAspect() {
logger = Logger.getLogger(ControllerExceptionAspect.class);
}
public ControllerExceptionAspect(Logger logger) {
this.logger = logger;
}
// Catching all exceptions from all methods in all controllers classes
@AfterThrowing(pointcut = "execution(* com.my.package..controller..*(..))", throwing = "exception")
public void afterThrowingAdvice(Exception exception) {
logger.error("CONTROLLER ASPECT: EXCEPTION IN METHOD -> " +
exception.getClass());
}
}
Aspect可以正常工作,但是很遗憾,我无法对其进行测试。我尝试了很多次,但是在Controller中模拟异常后却无法获取如何捕获Aspect方法的信息
@SuppressWarnings("ALL")
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextHierarchy({
@ContextConfiguration(classes = RootConfig.class),
@ContextConfiguration(classes = WebConfig.class)
})
public class ControllerExceptionAspectTest {
@Autowired
ApplicationContext applicationContext;
@Test
public void testControllerExceptionAspectGetsExecutedWhenExceptionOccures(){
HomeController homeController = (HomeController)applicationContext.getAutowireCapableBeanFactory().getBean("homeController");
try{homeController.callMethod("00000");}
catch (Exception e){}
ControllerExceptionAspect controllerExceptionAspect = (ControllerExceptionAspect)applicationContext.getAutowireCapableBeanFactory().getBean("controllerExceptionAspect");
// HOW TO CATCH THAT ASPECT METHOD WAS CALLED???
}
}
我认为您想要实现的是测试您创建的配置(方面切入点),而不是可以进行单元测试的方面本身。恐怕没有简单的方法可以实现这一目标。
您可以遵循一些有关捕获日志或其他想法的互联网建议。老实说,仅当您确实需要测试Aspect的预期行为时,我才测试它的预期行为。如果正在记录日志,我不会这样做。如果它为数据库设置了某些功能(或其他副作用),我将验证该值是否在数据库中。那就是集成测试的草草地面。
如果确实需要按自己的方式测试方面,则可以编写类似于给定代码的内容。但是请记住,正常的(非测试)运行时spring配置将需要Spring上下文中存在的Verifier接口的虚拟实现。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Config.class)
public class AspectTesting {
@Autowired
ServiceWithAspect service;
@Autowired
Verifier verifyingAspect;
@Test
public void test() {
// given
boolean condition = false;
// when
try {
service.doit();
} catch (Exception swallow) {}
// then
try {
condition = ((VerifyingAspect) ((Advised) verifyingAspect).getTargetSource().getTarget()).wasExecuted();
} catch (Exception swallow) {}
// then
Assert.assertTrue(condition);
}
}
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("aspects")
class Config {
}
@Component
class VerifyingAspect implements Verifier {
private boolean executed = false;
public boolean wasExecuted() {
return executed;
}
@Override
public void invoked() {
executed = true;
}
}
@Service
class ServiceWithAspect {
public void doit() {
throw new RuntimeException();
}
}
@Component
@Aspect
class TestedAspect {
@Autowired
Verifier verifier;
@AfterThrowing(pointcut = "execution(* *(..))", throwing = "exception")
public void afterThrowingAdvice(Exception exception) {
// your aspect logic here
verifier.invoked();
}
}
interface Verifier {
void invoked();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句