Arul
Arul

Reputation: 183

Spring boot unit junit testing not loading configuration

I am trying to unit test Spring Boot Application. As a part of main method, I'm invoking init method in Configuration service to do some data setup . Configuration service is autowired in Description service. When I try to unit test Description service, NPE is thrown as init method is not invoked in Configuration service. How to fix this.

BatchService:

@Configuration
@EnableAutoConfiguration
@ComponentScan("com.test.poc")
public class BatchService {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = null;
        SpringApplication application = new SpringApplication(BatchService.class);
        try{
            context =  application.run();
            //Initialize
            Configuration config = (Configuration)context.getBean("Configuration");
            config.init();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

ConfigurationService:

@Service
public class Configuration {
    private ConfigValue value = null;
    public void init(){
        //
    }
    public String getValue(){
        return value.getNameValue();
   }
}

DescriptionService:

@Service
public class DescriptionService {

    @Autowired Configuration config;

    public List<String> getDescription(){
        String value = config.getValue();
    }
}

AbstractAutonomicsTest:

@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BatchService.class)
@TestPropertySource(locations="classpath:application-test.properties")
public abstract class AbstractAutonomicsTest {

}

DescriptionClusteringServiceTest:

public class DescriptionClusteringServiceTest extends AbstractAutonomicsTest  {

    @Autowired DescriptionClusteringService descService;

    @Test
    public void testDescription(){
        List<String> out = descService.getDescription();
    }
}

Upvotes: 0

Views: 786

Answers (1)

M. Deinum
M. Deinum

Reputation: 124526

Instead of calling the method yourself, let the framework do it for you. Just annotate the init method with @PostConstruct to have it invoked after the dependencies have been injected.

@Service
public class Configuration {
    private ConfigValue value = null;

    @PostConstruct
    public void init(){
        //
    }
    public String getValue(){
        return value.getNameValue();
   }
}

Now you can also cleanup your BatchService. Note I suggest using @SpringBootApplication instead of 3 seperate annotations and if your BatchService is in the com.test.poc package (or a super package) you can remove the scanBasePackage or value from @ComponentScan.

@SpringBootApplication(scanBasePackages="com.test.poc").
public class BatchService {
    public static void main(String[] args) {
        SpringApplication.run(BatchService.class, args);
    }
}

Upvotes: 1

Related Questions