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.
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?
Thanks for the help.
example:
I have the following unit test:
@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));
}
}
and following service method:
@Override
@Transactional
@EventJournal(type = EventType.CAMPAIGN_CREATE, owner = EventOwner.TERMINAL_USER)
public Long createCampaign(Campaign campaign) {
return companyDao.saveCompany(campaign);
}
aspect:
@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);
}
}
When test executes - eventJournalService
is null. Thus I see NullPointerException
Limitations of Unit Testing Unit testing cannot detect integration or interfacing issues between two modules. It cannot catch complex errors in the system ranging from multiple modules. It cannot test non-functional attributes like usability, scalability, the overall performance of the system, etc.
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:
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.
So what can you do in a static if()
pointcut?
TestMode.ACTIVE
which is only true during unit or integration testingIf 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")
// ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With