Spring框架下AOP测试总结

通常我们会把日志,缓存等功能放到切面中实现。但是Aop的junit编写会是一个让人头疼的问题,经过探索发现利用AspectJProxyFactory手工生产代理类实现aop的测试是一个不错的主意,一来可以省却构建切面测试类的麻烦,二来可以测试下切面写的对不对。实现上并没有太多高深的内容,只是笔者在实际开发中的一点小的心得和总结希望给追求clean code的你一些参考。话不多说show my code:
Spring框架下AOP测试总结_第1张图片
这是一个简单的例子,其中Car类是返回的bean,CarCacheAop是ParkImpl切面类用的是@Around的方式来在真正调用getCar方法之前做一些缓存处理,如果缓存中能够查到则从缓存中获取如果获取不到则调用真实方法。具体代码逻辑如下:

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());  
  }  
}

运行结果如下:
Spring框架下AOP测试总结_第2张图片

从测试中可以发现,实现了我们的测试预期,第一个测试中当cache中有返回则方法实际返回的是缓存中的数据并且没有访问实际的Park类中的getCar方法。第二个测试中当cache中返回的为null,则访问了Park类中的getCar方法。

你可能感兴趣的:(java,aop,单元测试,junit)