Spring 集成测试:在使用 MockitoJUnitRunner 时注入 @Value

Spring integration tests: inject @Value while using MockitoJUnitRunner

下面的例子是正确的。问题是我确实需要 @InjectMocks 注释。当我用 MockitoJUnitRunner.class 替换 SpringJUnit4ClassRunner.class 时,一切都会中断(bar = null 而不是 testValue)。

如何解决?

//@RunWith(MockitoJUnitRunner.class) // not work (
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = FooTest.Config.class)
@TestPropertySource(properties = {
        "some.bar.value=testValue",
})
public class FooTest {

    @Value("${some.bar.value}")
    String bar;

    @Test
    public void testValueSetup() {
        assertEquals("testValue", bar);
    }

    @Configuration
    static class Config {

        @Bean
        public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
            return new PropertySourcesPlaceholderConfigurer();
        }
    }
}

您应该能够使用 ClassRule 和 Rule 的这种组合来启用 SpringRunner 所具有的相同功能。

    @ClassRule
    public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();

    @Rule
    public final SpringMethodRule springMethodRule = new SpringMethodRule();

然后像往常一样使用 MockitoRunner。

此外,您总是可以直接使用 Mockito.mock 等来模拟依赖项。如果测试不简单,注释方法虽然稍微干净一些,但会导致一些恼人的运行时问题,尤其是。在 @InjectMocks.

的情况下

想知道为什么 SpringBoot 项目中需要 Mockito 运行器吗?您可以在需要时使用 MockBeans 来模拟 Spring Beans。闻起来像 XY 问题,因为我从来没有使用过 MockitoRunner。

Mockito 还提供了一条规则来克服无法使用 MockitoJUnitRunner 的情况,例如:

@Rule
public MockitoRule mockito = org.mockito.junit.MockitoJUnit.rule();

...或者您可以手动设置 Mockito:

@Before 
public void setUp() {
    MockitoAnnotations.initMocks(this);
}