I have some basic yaml like
myThing:
someValue: 10
and I'm running my tests and running into formatting exceptions surrounding
TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:80)
where it's trying to parse strings to Integers, or Integers to Strings, or Strings to LocalDate, all things that my application is able to do fine when it boots up the entire Spring Boot context with an annotation like @SpringBootTest
edit: I'm thinking I'm just missing a necessary class for this behavior in @ContextConfiguration
but I can't find it for the life of me and I've spent hours on this.
package com.example.demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class MyThing {
@Value("${myThing.myValue}")
private Integer myValue;
public Integer getMyValue() {
return myValue;
}
}
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {MyThing.class}) // Won't be able to load the context
class DemoApplicationTests {
@Autowired
private MyThing myThing;
@Test
void contextLoads() {
assertEquals(10, myThing.getMyValue());
}
}
myThing:
myValue: 10
Caused by: java.lang.NumberFormatException: For input string: "${myThing.myValue}" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:654) at java.base/java.lang.Integer.valueOf(Integer.java:999) at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:203) at org.springframework.beans.propertyeditors.CustomNumberEditor.setAsText(CustomNumberEditor.java:115) at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:439) at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:412) at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:161) at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:80) ... 39 more
Using @SpringBootTest
loads the full context with the converter service and the test passes.
To be able to load properties from application.properties
file in test which is marked simple with @ExtendWith(SpringExtension.class)
and not with @SpringBootTest
, you must add ConfigDataApplicationContextInitializer.class
to the ContextConfiguration
annotation:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(
initializers = ConfigDataApplicationContextInitializer.class,
classes = MyThing.class
)
class Testik {
@Autowired
private MyThing myThing;
@Test
void contextLoads() {
assertEquals(10, myThing.getMyValue());
}
}