简体   繁体   中英

Spring bean methods don't use the field value injected by ReflectionTestUtils.setField

I have a spring project, which contains a class called EnvUtils :

package com.example;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
public class EnvUtils {

    @Value("${env}")
    private String env;

    /**
     * Develop environment
     */
    public boolean isDev() {
        return Objects.equals(env, "dev");
    }

    /**
     * Production environment
     */
    public boolean isProd() {
        return Objects.equals(env, "prod");
    }

}

I wrote a simple test, which set env 's value to dev , and checked the result of isDev() :

package com.example;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.util.ReflectionTestUtils;

@SpringBootTest
@ExtendWith(MockitoExtension.class)
class MainControllerTests {

    @MockBean
    private EnvUtils envUtils;

    @Test
    void fieldTest() {
        ReflectionTestUtils.setField(envUtils, "env", "dev");
        Assertions.assertTrue(envUtils.isDev());
    }

}

The test should pass because the value of env is dev , which means envUtils.isDev() should definitely return true . However, this test failed. I debugged it and found that envUtils.env was dev , as expected, but envUtils.isDev() returned false. How could it be? Have I done something wrong?

You are mocking EnvUtils class, so the method isDev is mocked also, the real method of the class will not be invoked.

In your case, you don't need @MockBean , remove it. And don't forget to initialize the envUrils object using default constructor.

@SpringBootTest
@ExtendWith(MockitoExtension.class)
class MainControllerTests {

    private EnvUtils envUtils = new EnvUtils();

    @Test
    void fieldTest() {
        ReflectionTestUtils.setField(envUtils, "env", "dev");
        Assertions.assertTrue(envUtils.isDev());
    }

}

You mocked whole EnvUtils class. If you change it to Spy it would be work. Read this: mock vs spy

Try this:

@ExtendWith(MockitoExtension.class)
class MainControllerTests {

    @SpyBean
    private EnvUtils envUtils;

    @Test
    void fieldTest() {
        ReflectionTestUtils.setField(envUtils, "env", "dev");
        Assertions.assertTrue(envUtils.isDev());
    }

}

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