在单元测试运行期间禁用某些方面

2022-09-02 14:00:23

我有集成测试(负载上下文)和单元测试一起运行。我的代码使用弹簧进行编译时编织。

我的问题是,我声明的建议也在我的一些单元测试期间运行。这扼杀了单元测试的概念,这就是为什么我想禁用它们。

有没有一些东西我可以放在切入点声明上,一些我可以调用的方法,一些弹簧配置,或者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, entity, null);
    }

    private void saveEvent(EventJournal eventJournal, EventStatus status, AbstractDomainEntity entity, Long persistentId)   {
        EventType type = eventJournal.type();
        EventOwner owner = eventJournal.owner();
        eventJournalService.saveEvent(type, owner, EventStatus.SUCCESS, entity, persistentId);
    }

}

当测试执行时 - 为空。因此,我看到eventJournalServiceNullPointerException


答案 1

答案很简单:您希望使用 if() 切入点表达式


更新(在问题也更新之后):上面最初提供的链接应该包含足够的信息,但对于它的价值,一个简短的解释和一个简单的例子:

切入点是返回 .如果返回值为 ,则表示任何组合的切入点只要匹配,就匹配。对于整个组合切入点的返回值不匹配,有效地停用与切入点相关的任何建议。if()staticbooleantruemyPointcut() && if()myPointcut()false

那么,在静态切入点中可以做些什么呢?if()

  • 评估某些工具类的静态布尔成员,例如仅在单元或集成测试期间为真TestMode.ACTIVE
  • 评估仅在测试期间设置的环境变量
  • 评估仅在测试期间设置的 Java 系统属性
  • 以及更多的事情

如果你想做一些更花哨(和更棘手)的事情,并且性能不是那么重要,你还可以尝试动态确定自动连接的坡向成员变量是否等于null,并且只有在注入的对象实际存在时才激活切入点。这里唯一的问题是如何从静态方法中确定成员变量。我对Spring AOP一无所知,但是在普通的AspectJ中,有一个帮助器类,其中包含几个名为的重载方法。假设您的方面被实例化为单例,您可以执行如下操作:AspectsaspectOf(..)

@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")
// ...

答案 2

我只能猜测:第一件事是有一个单独的Spring应用程序Context-test.xml,没有组件扫描;在 maven 中,您可以添加一个阶段运行时,其中不包括用于测试的编织罐。


推荐