问题摘要:
在常规运行期间(使用@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;
...
但是,问题出在单元测试期间,因为defaultsConfigProperties
是null
。
这是测试班:
@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
中创建它(如何?)?
答案 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);
}
因此,在您的情况下,您还应该删除测试类的注释以使其成为单元测试。