Spring Boot – How to init a Bean for testing?

In Spring Boot, we can create a @TestConfiguration class to initialize some beans for testing class only.

P.S Tested with Spring Boot 2

1. @TestConfiguration + @Import

This @TestConfiguration class will not pick up by the component scanning, we need to import it manually.

TestConfig.java

package com.mkyong;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;

import java.time.Duration;

@TestConfiguration
public class TestConfig {

    @Bean
    public RestTemplateBuilder restTemplateBuilder() {

        return new RestTemplateBuilder()
                .basicAuthentication("mkyong", "password")
                .setConnectTimeout(Duration.ofSeconds(5));
    }
}
RestTemplateTest.java

package com.mkyong;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
@Import(TestConfig.class)
public class RestTemplateTest {
    
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void post_user_ok() {
        //...
    }

}

2. @TestConfiguration + Inner Static Class

Alternatively, create a inner class like this :

RestTemplateTest.java

package com.mkyong;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringRunner;

import java.time.Duration;

@RunWith(SpringRunner.class)
@SpringBootTest
public class RestTemplateTest {

    @TestConfiguration
    static class TestConfig {

        @Bean
        public RestTemplateBuilder restTemplateBuilder() {

            return new RestTemplateBuilder()
                    .basicAuthentication("mkyong", "password")
                    .setConnectTimeout(Duration.ofSeconds(5));
        }
        
    }

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void post_user_ok() {
        //...
    }

}

References

4 comments on “Spring Boot – How to init a Bean for testing?

  1. Great Articles from MKyong. Its really helpful. Much appreciated.

    Reply
  2. Hi,

    I am trying to Autowire a non manned spring class – below –

    @TestConfiguration
    public class EasyRandomConfiguration {
    
        @Primary
        @Bean
        public EasyRandom easyRandom(){
             EasyRandomParameters parameters = new EasyRandomParameters()
                    .seed(123L)
                    .objectPoolSize(20)
                    .randomizationDepth(5)
                    .charset(Charset.forName("UTF-8"))
                    .timeRange(LocalTime.now().minusHours(24), LocalTime.now())
                    .dateRange(LocalDate.now().minusYears(20), LocalDate.now())
                    .stringLengthRange(5, 10)
                    .collectionSizeRange(1, 5)
                    .scanClasspathForConcreteTypes(true)
                    .overrideDefaultInitialization(false)
                    .ignoreRandomizationErrors(true);
             return new EasyRandom(parameters);
        }
    }
    

    And trying to Autowire in –

    @DataMongoTest
    @RunWith(SpringRunner.class)
    @Import(EasyRandomConfiguration.class)
    @ActiveProfiles("test")
    public class PersonRepositoryTest {
    
        @Autowired
        private PersonRepository personRepository;
    
        @Autowired
        private EasyRandom easyRandom;
    

    but getting following error – Any Suggesion

    java.lang.NullPointerException
    at com.kuberaya.core.test.repository.PersonRepositoryTest.<init>(PersonRepositoryTest.java:38)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:250)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:226)

    Reply
  3. “In Spring Boot, we can create a @TestConfiguration class to initialize some beans for testing class only. ” – not exactly truth. This will initialize all application beans plus those declared in @TestConfiguration configuration.

    Reply
    1. How can we only inject a specific bean in a JUnit test?

      Reply

Leave a Comment

Your email address will not be published. Required fields are marked *