摘要:首先先來看我們事先定義的以及。可以看到會修改方法的返回值,使其返回。例子測試的行為最簡單的測試方法就是直接調用,看看它是否使用返回。先看這段代碼這些是利用提供的和來判斷是否被代理了的實現是通過動態代理來做的。
Github地址
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的:
advised方法沒有返回值
Aspect不會修改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有三點區別:
啟用了MockitoTestExecutionListener,這樣能夠開啟Mockito的支持(回顧一下Chapter 3: 使用Mockito)
@SpyBean private FooAspect fooAspect,這樣能夠聲明一個被Mockito.spy過的Bean
verify(fooAspect, times(2)).changeIncrementAndGet(any()),使用Mockito測試FooAspect.changeIncrementAndGet是否被調用了兩次
上面的測試代碼測試的是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()); } }參考文檔
Aspect Oriented Programming with Spring
AopUtils
AopTestUtils
AopProxyUtils
spring源碼EnableAspectJAutoProxyTests
spring源碼AbstractAspectJAdvisorFactoryTests
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/70359.html
摘要:地址提供了,能夠很方便的來測試。同時也提供了更進一步簡化了測試需要的配置工作。本章節將分別舉例說明在不使用和使用下如何對進行測試。例子測試的關鍵是使用對象,利用它我們能夠在不需啟動容器的情況下測試的行為。 Github地址 Spring Testing Framework提供了Spring MVC Test Framework,能夠很方便的來測試Controller。同時Spring...
摘要:因為只有這樣才能夠在測試環境下發現生產環境的問題,也避免出現一些因為配置不同導致的奇怪問題。而方法則能夠不改變原有配置不提供新的配置的情況下,就能夠關閉。 Github地址 在Chapter 1: 基本用法 - 使用Spring Boot Testing工具里提到: 除了單元測試(不需要初始化ApplicationContext的測試)外,盡量將測試配置和生產配置保持一致。比如如果生產...
摘要:地址是提供的方便測試序列化反序列化的測試工具,在的文檔中有一些介紹。例子簡單例子源代碼見使用通包下的文件測試結果是否正確或者使用基于的校驗例子測試可以用來測試。這個例子里使用了自定義的測試代碼例子使用事實上也可以配合一起使用。 Github地址 @JsonTest是Spring Boot提供的方便測試JSON序列化反序列化的測試工具,在Spring Boot的文檔中有一些介紹。 需要注...
摘要:源代碼見需要注意的是,如果是專供某個測試類使用的話,把它放到外部并不是一個好主意,因為它有可能會被掃描到,從而產生一些奇怪的問題。 Github地址 既然我們現在開發的是一個Spring項目,那么肯定會用到Spring Framework的各種特性,這些特性實在是太好用了,它能夠大大提高我們的開發效率。那么自然而然,你會想在測試代碼里也能夠利用Spring Framework提供的特...
摘要:地址在使用工具中提到在測試代碼之間盡量做到配置共用。本章將列舉幾種共享測試配置的方法我們可以將測試配置放在一個里,然后在測試或中引用它。也可以利用的及自定義機制,提供自己的用在測試配置上。 Github地址 在使用Spring Boot Testing工具中提到: 在測試代碼之間盡量做到配置共用。...能夠有效利用Spring TestContext Framework的緩存機制,Ap...
閱讀 2179·2021-11-25 09:43
閱讀 2261·2021-11-24 09:39
閱讀 1555·2021-11-22 12:02
閱讀 2992·2021-11-17 09:33
閱讀 3418·2021-11-15 11:38
閱讀 2744·2021-10-13 09:40
閱讀 1075·2021-09-22 15:41
閱讀 1693·2019-08-30 10:58