Spring提供了一套AOP东西,可是当你把各类Aspect写完之后,如何确定这些Aspect都正确的应用到方针Bean上了呢?本章将举例说明如何对Spring AOP做测试。
首先先来看我们事先界说的Bean以及Aspect。
FooServiceImpl:
@Component public class FooServiceImpl implements FooService { private int count; @Override public int incrementAndGet() { count++; return count; } }
FooAspect:
@Component @Aspect public class FooAspect { @Pointcut("execution(* me.chanjar.aop.service.FooServiceImpl.incrementAndGet())") public void pointcut() { } @Around("pointcut()") public int changeIncrementAndGet(ProceedingJoinPoint pjp) { return 0; } }
可以看到FooAspect会修改FooServiceImpl.incrementAndGet要领的返回值,使其返回0。
例子1:测试FooService的行为
最简朴的测试要领就是直接挪用FooServiceImpl.incrementAndGet,昆山软件开发,看看它是否利用返回0。
SpringAop_1_Test:
@ContextConfiguration(classes = { SpringAopTest.class, AopConfig.class }) public class SpringAop_1_Test extends AbstractTestNGSpringContextTests { @Autowired private FooService fooService; @Test public void testFooService() { assertNotEquals(fooService.getClass(), FooServiceImpl.class); assertTrue(AopUtils.isAopProxy(fooService)); assertTrue(AopUtils.isCglibProxy(fooService)); assertEquals(AopProxyUtils.ultimateTargetClass(fooService), FooServiceImpl.class); assertEquals(AopTestUtils.getTargetObject(fooService).getClass(), FooServiceImpl.class); assertEquals(AopTestUtils.getUltimateTargetObject(fooService).getClass(), FooServiceImpl.class); assertEquals(fooService.incrementAndGet(), 0); assertEquals(fooService.incrementAndGet(), 0); } }
先看这段代码:
assertNotEquals(fooService.getClass(), FooServiceImpl.class); assertTrue(AopUtils.isAopProxy(fooService)); assertTrue(AopUtils.isCglibProxy(fooService)); assertEquals(AopProxyUtils.ultimateTargetClass(fooService), FooServiceImpl.class); assertEquals(AopTestUtils.getTargetObject(fooService).getClass(), FooServiceImpl.class); assertEquals(AopTestUtils.getUltimateTargetObject(fooService).getClass(), FooServiceImpl.class);
这些是操作Spring提供的AopUtils、AopTestUtils和AopProxyUtils来判定FooServiceImpl Bean是否被署理了(Spring AOP的实现是通过动态署理来做的)。
可是证明FooServiceImpl Bean被署理并不料味着FooAspect生效了(假设此时有多个@Aspect),昆山软件开发,那么我们还需要验证FooServiceImpl.incrementAndGet的行为:
assertEquals(fooService.incrementAndGet(), 0); assertEquals(fooService.incrementAndGet(), 0);
例子2:测试FooAspect的行为
可是总有一些时候我们是无法通过例子1的要领来测试Bean是否被正确的advised的:
那么这个时候怎么测试呢?此时我们就需要用到Mockito的Spy要领团结Spring Testing东西来测试。
SpringAop_2_Test:
@ContextConfiguration(classes = { SpringAop_2_Test.class, AopConfig.class }) @TestExecutionListeners(listeners = MockitoTestExecutionListener.class) public class SpringAop_2_Test extends AbstractTestNGSpringContextTests { @SpyBean private FooAspect fooAspect; @Autowired private FooService fooService; @Test public void testFooService() { // ... verify(fooAspect, times(2)).changeIncrementAndGet(any()); } }
这段代码和例子1有三点区别:
上面的测试代码测试的是FooAspect的行为,而不是FooServiceImpl的行为,这种测试要领更为通用。
例子3:Spring Boot的例子
上面两个例子利用的是Spring Testing东西,昆山软件开发,下面举例Spring Boot Testing东西如何测AOP(其实大同小异):
SpringBootAopTest:
@SpringBootTest(classes = { SpringBootAopTest.class, AopConfig.class }) @TestExecutionListeners(listeners = MockitoTestExecutionListener.class) public class SpringBootAopTest extends AbstractTestNGSpringContextTests { @SpyBean private FooAspect fooAspect; @Autowired private FooService fooService; @Test public void testFooService() { // ... verify(fooAspect, times(2)).changeIncrementAndGet(any()); } }