欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

FooServiceImpl.class); assertEquals(Ao 昆山软件定制开发 pTestUtils.

点击: 次  来源:劳务派遣管理系统 时间:2017-12-16

原文出处: chanjarster

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的:

  1. advised要领没有返回值
  2. 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有三点区别:

  1. 启用了MockitoTestExecutionListener,这样可以或许开启Mockito的支持(回首一下Chapter 3: 利用Mockito)
  2. @SpyBean private FooAspect fooAspect,这样可以或许声明一个被Mockito.spy过的Bean
  3. 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());

  }

}