Spring框架下AOP測試總結

一般咱們會把日誌,緩存等功能放到切面中實現。可是Aop的junit編寫會是一個讓人頭疼的問題,通過探索發現利用AspectJProxyFactory手工生產代理類實現aop的測試是一個不錯的主意,一來能夠省卻構建切面測試類的麻煩,二來能夠測試下切面寫的對不對。實現上並無太多高深的內容,只是筆者在實際開發中的一點小的心得和總結但願給追求clean code的你一些參考。話很少說show my code:
image.png
這是一個簡單的例子,其中Car類是返回的bean,CarCacheAop是ParkImpl切面類用的是@Around的方式來在真正調用getCar方法以前作一些緩存處理,若是緩存中可以查到則從緩存中獲取若是獲取不到則調用真實方法。具體代碼邏輯以下:spring

package com.moon.dong.demo.aop;  
  
import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.annotation.Around;  
import org.aspectj.lang.annotation.Aspect;  
  
@Aspect  
public class CarCacheAop {  
  
    private CarCache cache;  
  
  @Around("execution(public \* com.moon.dong.demo.aop.ParkImpl.getCar(..)) && args(id)")  
    public Object process(ProceedingJoinPoint joinPoint, String id) throws Throwable {  
        Car car = cache.getCar(id);  
 if (car != null){  
            return car;  
  }else {  
            return joinPoint.proceed(joinPoint.getArgs());  
  }  
    }  
}

測試類的邏輯以下:緩存

package com.moon.dong.demo.aop;  
  
import org.junit.Before;  
import org.junit.Test;  
import org.junit.runner.RunWith;  
import org.mockito.InjectMocks;  
import org.mockito.Mock;  
import org.mockito.Spy;  
import org.mockito.junit.MockitoJUnitRunner;  
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;  
  
import static org.junit.Assert.assertEquals;  
import static org.mockito.Matchers.anyString;  
import static org.mockito.Mockito.atLeastOnce;  
import static org.mockito.Mockito.doReturn;  
import static org.mockito.Mockito.never;  
import static org.mockito.Mockito.verify;  
  
@RunWith(MockitoJUnitRunner.class)  
public class CarCacheAopTest {  
    @InjectMocks  
  private CarCacheAop aop;  
  
  @Mock  
  private CarCache cache;  
  
  @Spy  
  private ParkImpl park;  
  
 private Park proxy;  
  
  Car carFromCache \= new Car();  
  Car carFromPark \= new Car();  
  
  @Before  
  public void setUp() throws Exception {  
        AspectJProxyFactory factory = new AspectJProxyFactory(park);  
  factory.addAspect(aop);  
  proxy \= factory.getProxy();  
  
  doReturn(carFromPark).when(park).getCar(anyString());  
  }  
  
    @Test  
  public void process\_use\_cache() {  
  
        doReturn(carFromCache).when(cache).getCar(anyString());  
  
  Car car = proxy.getCar("1111");  
  
  assertEquals(carFromCache, car);  
  verify(cache, atLeastOnce()).getCar(anyString());  
  verify(park, never()).getCar(anyString());  
  }  
  
    @Test  
  public void process\_use\_park() {  
  
        doReturn(null).when(cache).getCar(anyString());  
  
  Car car = proxy.getCar("1111");  
  
  assertEquals(carFromPark, car);  
  verify(cache, atLeastOnce()).getCar(anyString());  
  verify(park, atLeastOnce()).getCar(anyString());  
  }  
}

運行結果以下:
image.png測試

從測試中能夠發現,實現了咱們的測試預期,第一個測試中當cache中有返回則方法實際返回的是緩存中的數據而且沒有訪問實際的Park類中的getCar方法。第二個測試中當cache中返回的爲null,則訪問了Park類中的getCar方法。spa

相關文章
相關標籤/搜索