验证在测试中调用的切入点



我有一个虚拟项目,我试图找出如何测试被触发的切入点。

我的项目由一个方面bean组成,它只是在调用foo方法后打印

@Component
@Aspect
public class SystemArchitecture {
@After("execution(* foo(..))")
public void after() {
System.out.println("@After");
}
}

和实现foo方法的FooServiceImpl

@Service
public class FooServiceImpl implements FooService{
@Override
public FooDto foo(String msg) {
return new FooDto(msg);
}
}

代码可以工作并且我可以看到"@After"正在打印到控制台,但是我不能通过编程检查是否使用下面的测试调用了after切入点。

@SpringBootTest
public class AspectTest {
@Autowired
private FooService fooService;
@Test
void shouldPass() {
fooService.foo("hello");
}
}

我也尝试过使用非bean代理,如https://stackoverflow.com/a/56312984/18224588所建议的,但这次我得到一个明显的错误cannot extend concrete aspect,因为我的间谍代理不再被视为一个方面:

public class AspectNoContextTest {
@Test
void shouldPass() {
FooService fooService = Mockito.mock(FooService.class);
SystemArchitecture systemArchitecture = Mockito.spy(new SystemArchitecture());

AspectJProxyFactory aspectJProxyFactory = new AspectJProxyFactory(fooService);
aspectJProxyFactory.addAspect(systemArchitecture);

DefaultAopProxyFactory proxyFactory = new DefaultAopProxyFactory();
AopProxy aopProxy = proxyFactory.createAopProxy(aspectJProxyFactory);
FooService proxy = (FooService) aopProxy.getProxy();
proxy.foo("foo");
verify(systemArchitecture, times(1)).after();
}
} 

好的,经过一番挖掘,我发现可以通过使一个方面成为@SpyBean来实现这一点。AopUtils也可以用于执行额外的检查

@SpringBootTest
public class AspectTest {
@Autowired
private FooService fooService;
@SpyBean
private SystemArchitecture systemArchitecture;
@Test
void shouldPass() {
assertTrue(AopUtils.isAopProxy(fooService));
assertTrue(AopUtils.isCglibProxy(fooService));

fooService.foo("foo");
verify(systemArchitecture, times(1)).after();
}
}

最新更新