'How to avoid spring AOP aspect being called during test

I need to avoid an aspect being called when unit testing a class.

I'm working with Java 8, spring 4.3.22.RELEASE and mockito. I have a @Service and a unit test for it. I also have an @Aspect that defines a pointcut on a method in the service and it is working fine when I run my application. The problem is when I run my unit test, the aspect is called and a NullPointerException is raised because of a missing dependency in the aspect.

Service class:

@Service
public class ContactService {

    @Autowired
    public InContactService(ContactDao contactDao) {
        this.contactDao = contactDao;
    }

    public boolean muteCall(Long contactId) {
        return contactDao.muteCall(contactId);
    }
}

Service test:

public class ContactServiceTest {

  @Mock
  private ContactDao contactDao;

  private ContactService contactService;


  @Before
  public void setUp(){
    MockitoAnnotations.initMocks(this);
    contactService = new ContactService(contactDao);
  }

  @Test
  public void testMuteCall(){
    contactService.muteCall(1L);
  }
}

Aspect:


@Aspect
public class ContactAspect {

    private MeterRegistry registry;

    public void setRegistry(MeterRegistry registry) {
        this.registry = registry;
    }

    @AfterReturning(pointcut = "execution(* com.company.ContactService.muteCall(..))", returning = "retVal")
    public void checkReturnContactServiceMuteCall(JoinPoint joinPoint, boolean retVal) {
        Object[] args = joinPoint.getArgs();

      registry.counter("my.metric.mute_call").increment();
    }
}

Application context:

@Configuration
public class ApplicationContext {

    @Bean
    public MeterRegistry meterRegistry() {
      return new SimpleMeterRegistry();
    }

    @Bean
    public ContactAspect contactAspect() {
        ContactAspect aspect =   Aspects.aspectOf(ContactAspect.class);
        aspect.setRegistry(meterRegistry());
        return aspect;
    }
}

I expected that when the test is ran the aspect is not called. Currently I get a NullPointerException when I run the test because registry is not defined in the aspect.



Solution 1:[1]

The best approach is using Spring profiles, which allows you to have different running schemes.

check this: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html

Solution 2:[2]

I ran into this issue with legacy code to which I wanted to add integration tests but didn't need or want the aspects to be invoked.

There most likely is somewhere in your context configuration telling the application to enable aspects. Wherever that is, find it, and disable it.

In my case, the configs were XML based so in my applicationContext-services-integration-test.xml file being loaded for my integration tests, I commented out <aop:aspectj-autoproxy /> and it bypassed all the aspects for my tests.

Cheers!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ahmadreza Sedighi
Solution 2 ccu