Why @Value are always null when run unit-test?

Viewed 1960

I write the Spring Boot app and I come up with a conditional scheduling service idea. I decided to populate all properties from application-test.yml via @Value and put it in the HashMap.

What I don't understand why during unit-testing it always null, independently of if it is in a HashMap or @Value populated property.

ReportService.java:

@Component
public class ReportService {

    @Value("${reports.name}")
    private String name;

    @Value("${reports.enabled}")
    private Boolean enabled;

    private final Map<String, Boolean> enabledReports = new HashMap<String, Boolean>() {{
        put(name, enabled);
    }};


    boolean isEnabled(String reportName) {
        System.out.println(enabledReports.keySet() + " : " + enabledReports.values());
        System.out.println(name);

        return false;
    }
}

ReportServiceTest.java:

@SpringBootTest
@SpringBootConfiguration
@RunWith(SpringRunner.class)
@TestPropertySource(locations="classpath:application-test.yml")
@EnableAutoConfiguration
public class ReportServiceTest {

    private ReportService reportService = new ReportService();

    @Test
    public void test() {
        reportService.isEnabled("reportName");
    }

} 

application-test.yml:

reports:
  name: "report"
  enabled: false

What am I doing wrong?

2 Answers

reportService = new ReportService(); - you are creating instance of class yourself, how can Spring know that something needs to be injected?

Just let Spring to create instance for you (eg. via @Autowired):

@Autowired
private ReportService reportService;

Try to construct the map after the variables are initialized and also use @Autowired like https://stackoverflow.com/users/1121249/rkosegi mentioned:

@PostConstruct
public Map<String, Boolean> getEnabledReports(){
    Map<String, Boolean> stringBooleanMap = new HashMap<>();
    stringBooleanMap.put(name, enabled);
}
Related