Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Junit Tests with Spring Boot Actuator gives Exception

When I enable Actuators in my Spring Boot application, my Junit tests failed with a NullPointer Exception. The actuators are working fine, and the tests were working fine before I added the actuator artifact in my pom.xml file.

Seems like the

@MockBean
MailSender mailSender;

is causing the problem

My pom.xml file:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

My Test:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureTestDatabase
public class MailServiceTest extends CommonServiceTest {

    @Autowired
    MailService mailService;

    @MockBean
    MailSender mailSender;

    private static final String TO = "[email protected]";
    private static final String SUBJECT = "Subject";
    private static final String TEXT = "Text";
    private static final String TOKEN = "1234";

    @Value("${app.email.from}")
    private String fromEmail;

    @Value("${app.email.support}")
    private String supportEmail;

    private ArgumentCaptor<SimpleMailMessage> simpleMailMessageCaptor;

    @Override
    public void initObjects() {
        simpleMailMessageCaptor = ArgumentCaptor.forClass(SimpleMailMessage.class);
    }

    @Override
    public void initMocks() {

    }

    @Test
    public void sendMailTest() {

        mailService.sendMail(TO, SUBJECT, TEXT);

        verify(mailSender).send(simpleMailMessageCaptor.capture());

        assertEquals(TO, simpleMailMessageCaptor.getValue().getTo()[0]);
        assertEquals(SUBJECT, simpleMailMessageCaptor.getValue().getSubject());
        assertEquals(fromEmail, simpleMailMessageCaptor.getValue().getFrom());
        assertEquals(TEXT, simpleMailMessageCaptor.getValue().getText());
    }

}

The error:

java.lang.IllegalStateException: Failed to load ApplicationContext

    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mailHealthIndicator' defined in class path resource [org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration$MailHealthIndicatorConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.health.HealthIndicator]: Factory method 'mailHealthIndicator' threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1128)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1023)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:111)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 29 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.health.HealthIndicator]: Factory method 'mailHealthIndicator' threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 46 more
Caused by: java.lang.NullPointerException
    at org.springframework.boot.actuate.autoconfigure.CompositeHealthIndicatorConfiguration.createHealthIndicator(CompositeHealthIndicatorConfiguration.java:42)
    at org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration$MailHealthIndicatorConfiguration.mailHealthIndicator(HealthIndicatorAutoConfiguration.java:334)
    at org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration$MailHealthIndicatorConfiguration$$EnhancerBySpringCGLIB$$25b5897.CGLIB$mailHealthIndicator$0(<generated>)
    at org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration$MailHealthIndicatorConfiguration$$EnhancerBySpringCGLIB$$25b5897$$FastClassBySpringCGLIB$$da72ce26.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356)
    at org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration$MailHealthIndicatorConfiguration$$EnhancerBySpringCGLIB$$25b5897.mailHealthIndicator(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 47 more
like image 563
Leamas Avatar asked Dec 20 '16 16:12

Leamas


People also ask

What value does spring boot actuator provide?

What value does Spring Boot Actuator provide? Spring Boot actuator allows you to monitor and interact with your application which is very important for a production application. Without a spring boot actuator, you need to build your own monitoring and interaction system using JMX.

How does actuator work in spring boot?

Actuator is mainly used to expose operational information about the running application — health, metrics, info, dump, env, etc. It uses HTTP endpoints or JMX beans to enable us to interact with it. Once this dependency is on the classpath, several endpoints are available for us out of the box.

How do I enable actuators in spring boot?

To enable Spring Boot actuator endpoints to your Spring Boot application, we need to add the Spring Boot Starter actuator dependency in our build configuration file. Maven users can add the below dependency in your pom. xml file. Gradle users can add the below dependency in your build.


1 Answers

The only solution I found was to add a properties in the test itself:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureTestDatabase
// Otherwise I have a NullPointer, don't know why
@TestPropertySource(
        properties = {"management.health.mail.enabled=false"})
public class MailServiceTest extends CommonServiceTest {
like image 139
Leamas Avatar answered Sep 22 '22 01:09

Leamas