我有集成测试(加载上下文)和单元测试一起运行.我的代码使用
spring编译时间编织.
我的问题是我宣布的建议也在我的单元测试期间运行.这会杀死单元测试的概念,这就是为什么我要禁用它们.
有没有什么可以放在切入点的声明,一些方法我可以调用,一些spring配置,或maven命令禁用这些建议像所有* UnitTest.java?
谢谢您的帮助.
例:
我有以下单元测试:
@RunWith(MockitoJUnitRunner.class) public class CompanyServiceImplTest { @Test public void createCampaignTest() throws Exception { when(companyDaoMock.saveCompany(any(Campaign.class))).thenReturn(77L); Long campaignId = companyService.createCampaign(campaignMock); assertEquals(Long.valueOf(77L),Long.valueOf(campaignId)); } }
和服务方式:
@Override @Transactional @EventJournal(type = EventType.CAMPAIGN_CREATE,owner = EventOwner.TERMINAL_USER) public Long createCampaign(Campaign campaign) { return companyDao.saveCompany(campaign); }
方面:
@Aspect public class EventJournalAspect { @Autowired private EventJournalService eventJournalService; @Pointcut(value="execution(public * *(..))") public void anyPublicMethod() {} @Pointcut("within(com.terminal.service..*)") private void inService() {} @AfterReturning(pointcut = "anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,..)",returning = "id") public void process(Object id,EventJournal eventJournal,AbstractDomainEntity entity) throws Throwable { if (eventJournal.type() != EventType.CAMPAIGN_PAYMENT || id != null) { saveEvent(eventJournal,EventStatus.SUCCESS,entity,(Long) id); } } @AfterThrowing(pointcut = "anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,throwing="ex") public void processException(EventJournal eventJournal,AbstractDomainEntity entity,Exception ex) throws Throwable { saveEvent(eventJournal,EventStatus.FAILURE,null); } private void saveEvent(EventJournal eventJournal,EventStatus status,Long persistentId) { EventType type = eventJournal.type(); EventOwner owner = eventJournal.owner(); eventJournalService.saveEvent(type,owner,persistentId); } }
当测试执行时 – eventJournalService为空.因此我看到NullPointerException
解决方法
答案很简单:你想使用一个
if()
pointcut expression.
更新(在问题也被更新之后):上面提供的最初链接应该包含足够的信息,但是对于什么是值得的,一个简短的解释和一个简单的例子:
if()切入点是返回布尔值的静态方法方法.如果返回值为true,则意味着任何组合的切入点,如myPointcut()&&只要myPointcut()匹配,if()就匹配.对于返回值为false,整个组合切入点不匹配,有效地禁用与切入点相关的任何建议.
那么你可以在静态if()切入点做什么?
>评估一些类似TestMode.ACTIVE的工具类的静态布尔成员,这在单元或集成测试中是唯一的
>评估环境变量,该变量只在测试期间设置
>评估仅在测试期间设置的Java系统属性
>还有更多的东西
如果你想做一些优秀的人(而且很棘手),性能并不重要,你也可以尝试动态地确定自动连接的方面的成员变量是否等于null,只有当被注入的对象实际存在时才激活切入点.这里唯一的问题是如何从静态方法中确定成员变量.我不了解Spring AOP,但是在简单的AspectJ中,有一些帮助器类Aspects带有几个重载方法,名为aspectOf(..).假设你的方面被实例化为单身,你可以这样做:
@Pointcut("if()") public static boolean isActive() { return Aspects.aspectOf(PerformanceMonitorAspect.class).eventJournalService != null; } // ... @AfterReturning(pointcut = "isActive() && anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,returning = "id") // ... @AfterThrowing(pointcut = "isActive() && anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,throwing="ex") // ...