@Value 属性在 JUnit 测试中始终为 null

@Value properties are always null in JUnit test

我正在为 Spring 应用程序编写一些单元测试,该应用程序可以 运行 具有两种不同的配置。这两种不同的配置由两个 application.properties 文件给出。我需要为每个 class 编写两次测试,因为我需要验证与配置一起使用的更改不会影响另一个。

为此我在目录中创建了两个文件:

src/test/resources/application-configA.properties

src/test/resources/application-configB.properties

然后我尝试使用 @TestPropertySource 的两个不同值加载它们:

@SpringBootTest
@TestPropertySource(locations = "classpath:application-configA.properties")
class FooTest {
  @InjectMock
  Foo foo;

  @Mock
  ExternalDao dao;

  // perform test
}

Foo class 是这个:

@Service
public class Foo {
  @Autowired
  private External dao;

  methodToTest() {
    Properties.getExampleProperty();
    this.dao.doSomething(); // this needs to be mocked!
  }
}

而 class Properties 是:

@Component
public class Properties {
  private static String example;

  @Value("${example:something}")
  public void setExampleProperty(String _example) {
    example = _example;
  }

  public static String getExampleProperty() {
    return example;
  }
}

问题是 Properties.getExampleProperty() 在测试期间总是 returns null,而在正常执行中它包含正确的值。

我试过:

这些都不起作用。

我已经阅读了 this question 的答案,但看起来有些不同,它们对我没有帮助

我建议使用 @Before 以便在单元测试中设置值,如果它是针对整个 class 使用 org.springframework.test.util.ReflectionTestUtils

然而,为了这样做,您必须在测试中注入 Properties 个实例 class

@InjectMocks Properties properties;
...
@Before
  public void setUp() {
    ReflectionTestUtils.setField(properties, "example", "something");
  }

或者您也可以在 @Test 中使用相同的 ReflectionTestUtil - 我认为

更新: 您使用 @TestPropertySource 的方式绝对正确,但在使用术语 locationproperties 时可能存在一些冲突, 在我看来,我已经看到代码在做,

@TestPropertySource(properties = "classpath:application-configA.properties")

此外,您是否尝试添加 @ActiveProfile('test')@AutoConfigureMockMvc

经过多次尝试,终于找到了解决办法。该问题是由将 Spring 4 与 JUnit 5 一起使用引起的,即使它没有显示任何警告或错误,它也无法加载 Spring 上下文。老实说,我不知道 @SpringBootTest 在实践中做了什么。

解决方案是添加 spring-test-junit5 dependency as stated in ,然后执行以下步骤:

  • 删除 @SpringBootTest 注释
  • 添加 @ExtendWith(SpringExtension.class),从 spring-test-junit5
  • 导入 class
  • 添加@Import(Properties.class)

现在测试的注释如下所示:

@ExtendWith(SpringExtension.class)
@PropertySource("classpath:application-configA.properties")
@TestPropertySource("classpath:application-configA.properties")
@Import(Properties.class)
class FooTest {