如何在 Spring 引导中使用 @ConfigurationProperties 模拟 class

How to mock class with @ConfigurationProperties in Spring Boot

我有一个 class,它使用 @ConfigurationProperties 自动装配另一个 class。

Class 与@ConfigurationProperties

@ConfigurationProperties(prefix = "report")
public class SomeProperties {
    private String property1;
    private String property2;
...

Class Autowires 以上 class SomeProperties

@Service
@Transactional
public class SomeService {
    ....
    @Autowired
    private SomeProperties someProperties;
    .... // There are other things

现在,我想测试 SomeService class 并且在我的测试中 class 当我模拟 SomeProperties class,我得到所有属性的 null 值。

测试class

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SomeProperties.class)
@ActiveProfiles("test")
@EnableConfigurationProperties
public class SomeServiceTest {
    @InjectMocks
    private SomeService someService;

    @Mock // I tried @MockBean as well, it did not work
    private SomeProperties someProperties;

如何模拟 SomeProperties 具有来自 application-test.properties 文件的属性。

如果您正在使用 @Mock ,您还需要存根这些值。默认情况下,所有属性的值都将为空。

您需要在 SomeServiceTest.java 的 @Test/@Before 方法中存根所有 属性 值,例如:

ReflectionTestUtils.setField(someProperties, "property1", "value1");

ReflectionTestUtils.setField(object, name, value);

                         

您还可以通过 Mockito.when()

模拟依赖 类 的响应

如果您打算绑定属性文件中的值,则您不是在模拟 SomeProperties,在这种情况下,将提供 SomeProperties 的实际实例。

模拟:

@RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {

    @InjectMocks
    private SomeService someService;

    @Mock
    private SomeProperties someProperties;

    @Test
    public void foo() {
        // you need to provide a return behavior whenever someProperties methods/props are invoked in someService
        when(someProperties.getProperty1()).thenReturn(...)
    }

无 Mock(someProperties 是一个真实对象,它绑定了来自某些属性源的值):

@RunWith(SpringRunner.class)
@EnableConfigurationProperties(SomeConfig.class)
@TestPropertySource("classpath:application-test.properties")
public class SomeServiceTest {
   
    private SomeService someService;

    @Autowired
    private SomeProperties someProperties;

    @Before
    public void setup() {
        someService = new someService(someProperties); // Constructor Injection
    }
    ...