Java 在Spring引导的单元测试期间将配置对象注入服务bean

Java 在Spring引导的单元测试期间将配置对象注入服务bean,java,spring,unit-testing,spring-boot,configuration,Java,Spring,Unit Testing,Spring Boot,Configuration,问题摘要: 在常规运行期间(使用@Autowired)成功创建了配置对象,但在单元测试阶段运行时,配置对象为null 编辑,作为将问题标记为重复问题的响应: 我不认为这是重复的,因为我的问题是关于单元测试阶段,而上面的问题是关于常规运行阶段 详细说明: 我有一个读取属性文件的配置对象: @Configuration @ConfigurationProperties(prefix = "defaults") @Getter @Setter public class DefaultsConfigPr

问题摘要:

在常规运行期间(使用
@Autowired
)成功创建了配置对象,但在单元测试阶段运行时,配置对象为
null

编辑,作为将问题标记为重复问题的响应: 我不认为这是重复的,因为我的问题是关于单元测试阶段,而上面的问题是关于常规运行阶段

详细说明:

我有一个读取属性文件的配置对象:

@Configuration
@ConfigurationProperties(prefix = "defaults")
@Getter
@Setter
public class DefaultsConfigProperties {
   Double value;
   ....
在服务层,在常规模式下运行应用程序时,我成功地使用了此类:

@Service
@Configuration   
public class CatsService {

@Autowired
DefaultsConfigProperties defaultsConfigProperties;
...
但是,问题出现在单元测试期间,因为
defaultsconfigproperty
null

以下是测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@TestPropertySource(properties = {
    "defaults.value=0.2"
})
public class CatServiceTest {
private CatService;

@Before
public void before(){
    catService = new CatService();
}
如果理解正确,我需要在单元测试阶段以某种方式创建/注入/模拟
defaultsconfigproperty

我还知道不建议使用
@Autowired
,最好将项传递给类的构造函数。
因此,如果解决方案是,
CatService
将需要在构造函数中接受
DefaultsConfigProperty
,然后在
CatServiceTest

中创建它(如何?),那么您就在正确的轨道上了,正如您所说的,构造函数注入优于字段注入

然而,如果您想依赖字段注入,您可以使用
Mockito

单元测试中的使用示例:

@Mock
DefaultsConfigProperties defaultsConfigProperties;

@InjectMocks
private CatService;

@Before
public void before(){
    catService = new CatService();
    MockitoAnnotations.init(this);
}
因此,在您的情况下,您还应该删除测试类的注释,使其成为单元测试。

注释采用
classes
数组参数。如果要加载相同的
ApplicationContext
,可以将任何带有
@Configuration
注释的类以及包含主方法(
SpringApplication.run(…)
)的类传递到此数组中。就你而言:

@SpringBootTest(classes = {Application.class, DefaultsConfigProperties.class})

注意,您也可以直接使用
SpringRunner

您在这里做的两件事导致了完全不同的测试场景。(1) 您正在使用Spring在测试中创建一个值为
0.2
DefaultsConfigProperties
。在这种情况下,副本仍然有效,因为您正在自行创建
CatService
。(2) 或者,您尝试创建一个虚拟的
DefaultsConfigProperties
类,但在这种情况下,您不需要
@springbootest
@TestPropertySource
。由于这种重复仍然适用于情况(1),除非你在你的问题中澄清这一点,否则我不会投票重新开始。