简体   繁体   中英

Junit 5 mockito unable to read properties file annotated with @Value in spring boot application

I am writing a junit test cases for one of component in spring boot application. That component is having @Valu e annotation and reading value from property file.

When I am running my Junit 5 (mockito) and controls goes to the component; the value is null.

What I have tried: I used @ExtendWith(SpringRunner) and changed @injectMocks to @Autowired and @mock to @MockBeans , but that is not I want (As its became integration test.)

Junit class:

@ExtendWith(MockitoExtension.class)
public class ItemMessageProcessorTest {

    private static final String VALUE1 = "Value 1";
    private static final String VALUE2 = "Value 2";
    private static final String VALUE3 = "Value 3";

    @InjectMocks
    private MyComponent component;

    

Component class:

@Slf4j
@Component
public class MyComponent {

    @Value("${my-val.second-val.final-val}")
    private String myValue;

This myValue is being used here in the same component class:

 public void myMethod(){
    myObject.setMyValue(Integer.parseInt(myValue));
}

What I was looking for is something like: If I can by any chance mock the parseInt, or load the values from test class itself. Any lead would be a great help. Note: I can't change anything in the component class.

您可以使用 Spring 反射 utills 方法使用 @Value 设置字段值进行单元测试:

org.springframework.test.util.ReflectionTestUtils.setField(classUnderTest, "field", "value");

Values from application.properties are loaded into Spring Application Context in these cases:

  • when application is running,
  • when Spring Integration tests are runnign.

In case of Unit tests properties are not loaded.

If you'd have a constructor injection you could set a value for tests and pass it to the constructor.

I would go for constructor injection in this case:

@Slf4j
@Component
public class MyComponent {

    private final String myValue;

    MyComponent(@Value("${my-val.second-val.final-val}" String myValue)) {
        this.myValue = myValue;
    }
}

Most important thing, you don't want to load the entire Spring Application context to bind the properties automatically as this would hugely slow down the execution of the unit tests. Therefore, you cannot use @ExtendWith(SpringRunner).

You can make use of ReflectionTestUtils along with @ExtendWith(MockitoExtension.class) to bind the properties of MyComponent class.

org.springframework.test.util.ReflectionTestUtils.setField(MyComponent.class, "myValue", 1);

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