在单元测试运行期间禁用某些方面 [英] Disabling certain aspects during unit test runs
问题描述
我有集成测试(负载上下文)和单元测试一起运行.我的代码使用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()
切入点是返回boolean
的static
方面方法.如果返回值是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屋!