在单元测试运行期间禁用某些方面 [英] Disabling certain aspects during unit test runs

查看:85
本文介绍了在单元测试运行期间禁用某些方面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have integration tests (load context) and unit tests running together. My code does aspectj compile time weaving using spring.

我的问题是,在某些单元测试中,我声明的通知也同时运行.这扼杀了单元测试的概念,这就是为什么我要禁用它们的原因.

My problem is that my declared advises also run during some of my unit tests. This kills the notion of a unit test, which is why I would like to disable them.

是否可以在切入点声明中放置某些内容,可以调用的某些方法,某些spring配置或禁用所有* UnitTest.java之类的建议的maven命令?

Is there something I can put on the pointcut declaration, some method I can call, some spring configuration, or maven command that disables these advises for something like all *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);
    }

}

执行测试时-eventJournalService为空.因此,我看到NullPointerException

When test executes - eventJournalService is null. Thus I see NullPointerException

推荐答案

答案很简单:您想使用

The answer is simple: You want to use an if() pointcut expression.

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

Update (after the question has also been updated): The originally provided link above should contain enough information, but for what it is worth, a short explanation and a simple example:

if()切入点是返回booleanstatic方面方法.如果返回值是true,则意味着只要myPointcut()匹配,任何匹配的切入点(如myPointcut() && if())都将匹配.对于返回值false,整个组合切入点都不匹配,从而有效地停用了与切入点相关的所有建议.

An if() pointcut is a static aspect method returning a boolean. If the return value is true, it means that any combined pointcut like myPointcut() && if() matches as long as myPointcut() matches. For a return value of false the whole combined pointcut does not match, effectively deactivating any advice connected to the pointcut.

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

So what can you do in a static if() pointcut?

  • 评估某些工具类(例如TestMode.ACTIVE)的静态布尔成员,该成员仅在单元测试或集成测试中为真
  • 评估仅在测试期间设置的环境变量
  • 评估仅在测试期间设置的Java系统属性
  • 还有更多东西
  • evaluate a static boolean member of some tool class like TestMode.ACTIVE which is only true during unit or integration testing
  • evaluate an environment variable which is only set during testing
  • evaluate a Java system property which is only set during testing
  • and many more things

如果您想做一些更奇妙的事情(而更棘手的事情),而性能并不是那么重要,那么您也可以尝试动态确定自动装配的Aspect成员变量是否等于null,并且仅当注入的对象为时才激活切入点.实际存在.唯一的问题是如何从静态方法确定成员变量.我对Spring AOP一无所知,但在普通的AspectJ中,有一个帮助器类Aspects,它带有多个名为aspectOf(..)的重载方法.假设您的方面被实例化为一个单例,则可以执行以下操作:

If you want to do something fancier (and trickier) and performance is not so important, you can also try to dynamically determine whether the auto-wired aspect member variable equals null or not and only activate your pointcuts if the injected object is actually present. The only problem here is how to determine a member variable from a static method. I have no idea about Spring AOP, but in plain AspectJ there is the helper class Aspects with several overloaded methods named aspectOf(..). Assuming that your aspect is instantiated as a singleton, you could do something like this:

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

这篇关于在单元测试运行期间禁用某些方面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆