spring-bootjunitjunit5spring-boot-test

SpringBoot 2 + Junit5: null with @Value


I have an application with SpringBoot2 and Junit5, and now I'm trying to make a test. I have a this class called OrderService that looks like this:

@Component
public class OrderService {
@Value("#{'${food.requires.box}'.split(',')}")
private List<String> foodRequiresBox;

@Value("#{'${properties.prioritization}'.split(',')}")
private List<String> prioritizationProperties;

@Value("${further.distance}")
private Integer slotMeterRange;

@Value("${slot.meters.long}")
private Double slotMetersLong;

As you can see, the class has many @Value annotations that extracts values from application.properties file.

In the POM file I have these dependences:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.1.0</version>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>RELEASE</version>
</dependency>
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-launcher</artifactId>
    <version>1.1.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <version>2.0.5.RELEASE</version>
</dependency>

Tn the test/resources folder I have the application.properties file with this information:

properties.prioritization:vip,food
food.requires.box:pizza,cake,flamingo
further.distance:2
slot.meters.long:0.5

The test file looks like this:

@ExtendWith(SpringExtension.class)
@TestPropertySource(locations="classpath:application.properties")
public class OrderServiceTest {
    OrderService orderService;

    @BeforeEach
    void before(){
        orderService = new OrderService();
    }

    @Test
    void findAll() {
        Order order = new Order().withDescription("2x Pizza with Salad\\n2x Kebab with Fries\\n1x Hot dog with Fries\\n2x Pizza with Fries");
        assertTrue(orderService.orderHasFood.test(order));
    }
}

But the test throws NullPointerException when it tries to use foodRequiresBox, so there is a problem to read the application.properties file.

Could you tell how can I read the application.properties file for the tests?


Solution

  • 1st Solution

    I would recommend to use Spring's internal annotation called @SpringJUnitConfig This annotation is actually the same as @ExtendWith(SpringExtension.class) BUT you can configure your spring application contexts for your test in the same way you used to use @ContextConfiguration.

    Or if you want a full Spring Boot Test you could just combine:

    @SpringJUnitConfig
    @SpringBootTest
    public class OrderServiceTest {
    ...
    }
    

    2nd Solution

    Another way is to not use Spring at all, but mock all the internal stuff with e.g. Mockito and write a plain simple Unit Test. You could then set your normally via Spring injected annotated @Value fields via org.springframework.test.util.ReflectionTestUtils.