Home > Back-end >  How to populate yml property file in JUnit 5 test without build spring context
How to populate yml property file in JUnit 5 test without build spring context

Time:04-04

Let's say that I have a service that took a property file from the application.yml file:

orders:
  batch-size: 2

and read by @Value annotation:

@Value("${orders.batch-size}")
private String ordersBatchSize;

to conduct data partitioning.

I am writing the JUnit tests and would like to get the above property from the application.yml file which is in the resources. Problem is that the JUnit test property is always null. My JUnit class test is annotated with @ExtendWith(MockitoExtension.class). I don't want to build Spring context by annotating the class with @SpringBootTest. According to this, I need to populate the property file but I tried probably everything without a desirable result.

Attempts so far:

ReflectionTestUtils.setField(classUnderTest, "field", "value")

or

Yaml yaml = new Yaml();
InputStream inputStream =this.getClass().getClassLoader().getResourceAsStream("application.yml");
yaml.load(inputStream);

or

Properties properties = new Properties();
properties.load(new FileReader("/application.properties"));

or

System.setProperty("orders.batch-size", "2");

or:

public static Properties fetchProperties() {
        Properties properties = new Properties();
        try {
            File file = ResourceUtils.getFile("classpath:application.yml");
            InputStream in = new FileInputStream(file);
            properties.load(in);
        } catch (IOException e) {
          // exception logic
        }
    return properties;
}

or hints from this topic but it didn't bring a desirable solution.

I will be grateful for suggestions on how to fix this issue. Cheers!

CodePudding user response:

First of all, the type should be an integer.

@Value("${orders.batch-size}")
private Integer ordersBatchSize;

Then using the reflections utils is quite a common approach. Note the field name has to match.

ReflectionTestUtils.setField(classUnderTest, "ordersBatchSize", 100)

A better way is using a setter (if available) in the method annotated with @BeforeEach.

@BeforeEach
public void beforeEach() {
    classUnderTest.setOrdersBatchSize(100);
}

Finally, the best way is to define application.yml in the test/resources folder which Spring Boot takes with priority for sake of testing:

orders.batch-size=100
  • Related