Search code examples
javaspringspring-bootjunitspring-config

Secondary type dependency injection does not work in spring boot


As per the documentation, spring boot will automatically check the bean class object created in any classes annotated with @Configuration & will override the default bean of that class & return the object with any properties that are injected as it is defined. But when i test this application in junit, it does not return any value that is being injected. All my classes are defined in the same package My code is as below,

//Engine class

package com.test.simpletest;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Engine {

private String msg;

public Engine() {
    System.out.println("Engine class is being called");
}

public String getMsg() {
    return msg;
}

public void setMsg(String msg) {
    this.msg = msg;
}
}

//Test configuration class

package com.test.simpletest;

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;

@Configuration
public class TestConfiguration{

@Bean
public Engine engine() {
    Engine eng = new Engine();
    eng.setMsg("Message is being called");
    return eng;
}
}

//Spring boot main app

package com.test.simpletest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SimpleTestExampleApplication {

public static void main(String[] args) {
    SpringApplication.run(SimpleTestExampleApplication.class, args);
}
}

//JUnit Test class

package com.test.simpletest;

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.context.ApplicationContext;
import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;

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

@Autowired 
private Engine engine; 

@Test
public void contextLoads() {

    engine.getMsg();

//Both above and below approach does not work 

//      ApplicationContext apx = new 
AnnotationConfigApplicationContext(TestConfiguration.class);
//      Engine engine = (Engine)apx.getBean(Engine.class);
//      engine.getMsg();
}
}

Please help me in finding a solution to the above problem.


Solution

  • DemoApplication

    @SpringBootApplication
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
    
        }
    }
    

    Engine

    public class Engine {
        private String msg;
    
        public Engine() {
            System.out.println("Engine class is being called");
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
    

    TestConfiguration

    @Configuration
    public class TestConfiguration {
        @Bean
        public Engine getEngine() {
            Engine eng = new Engine();
            eng.setMsg("Message is being called");
            return eng;
        }
    }
    

    DemoApplicationTests

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @Import(TestConfiguration.class)
    public class DemoApplicationTests {
    
        @Autowired
        private Engine engine;
    
        @Test
        public void contextLoads() {
            System.out.println("engine : " + engine.getMsg());
        }
    
    }
    

    Output

    Engine class is being called
    engine : Message is being called