简体   繁体   中英

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?

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 eg 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 .

I'd recommend using org.springframework.test.util.ReflectionTestUtils (as indicated in @mrkernelpanic second solution) using the setField() method, in order to avoid initializing the full Spring context.

Here is a snippet:

// ReflexionTestUtils.setField(targetObject, "targetFieldName", valueToInject);
ReflexionTestUtils.setField(orderService, "foodRequiresBox", "pizza,cake,flamingo");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM