在Spring Boot的单元测试期间将配置对象注入服务Bean

时间:2018-09-17 07:36:05

标签: java spring unit-testing spring-boot configuration

问题摘要:

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

编辑,以将问题标记为重复: 我认为这不是Why is my Spring @Autowired field null?的重复,因为我的问题与单元测试阶段有关,而上述问题与常规运行阶段有关。

详细信息:

我有一个配置对象,可以读取属性文件:

@Configuration
@ConfigurationProperties(prefix = "defaults")
@Getter
@Setter
public class DefaultsConfigProperties {
   Double value;
   ....

在服务层中,以常规模式运行应用程序时,我正在成功使用此类:

@Service
@Configuration   
public class CatsService {

@Autowired
DefaultsConfigProperties defaultsConfigProperties;
...

但是,问题出在单元测试期间,因为defaultsConfigPropertiesnull

这是测试班:

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

@Before
public void before(){
    catService = new CatService();
}

如果我理解正确,则需要在单元测试阶段以某种方式创建/注入/模拟DefaultsConfigProperties类。

我也知道不建议使用@Autowired,最好将项目传递给类的构造函数。 因此,解决方案应该是CatService是否需要在构造函数中接受DefaultsConfigProperties,然后在CatServiceTest中创建它(如何?)?

2 个答案:

答案 0 :(得分:1)

@SpringBootTest批注采用classes数组参数。您可以将任何带有@Configuration的类传递给该数组,也可以将包含主方法(SpringApplication.run(...))的类传递给数组(如果要加载相同的ApplicationContext)。就您而言:

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

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

答案 1 :(得分:0)

您处于正确的轨道,因为您说构造函数注入优先于字段注入。

尽管如此,如果您希望依靠电场注入,可以使用Mockito

在单元测试中的使用示例:

@Mock
DefaultsConfigProperties defaultsConfigProperties;

@InjectMocks
private CatService;

@Before
public void before(){
    catService = new CatService();
    MockitoAnnotations.init(this);
}

因此,在您的情况下,您还应该删除测试类的注释以使其成为单元测试。