[英]Autowired field is null when testing
我正在尝试测试我的应用程序中的一个简单谓词。 这个谓词使用存储库来检查一些数据,但是当我测试它时,存储库总是null
,即使它在实际上下文中运行良好。
这是谓词:
@Slf4j
public class NameChangePredicate implements ValidationPredicate {
@Autowired
NameChangeRepository nameChangeRepository;
String errorCode;
GeographicZone zone;
public NameChangePredicate(String errorCode, GeographicZone zone) {
super();
this.errorCode = errorCode;
this.zone = zone;
}
/**
* Test the condition
*
* @param response the {@link ValidationServiceResponse}
* @return true if valid
*/
@Override
public boolean test(ValidationServiceResponse response) {
if (!StringUtils.isBlank(response.getClass()) && zone != null) {
List<NameChange> nameChanges = nameChangeRepository.findAllByGeographicZoneId(zone.getId());
if (nameChanges.stream().anyMatch(n -> n.getClasses().stream().anyMatch(response.getClass()::equalsIgnoreCase))) {
return true;
}
}
throw new ValidationException(this.errorCode);
}
}
这是我的简单测试:
@ActiveProfiles("test")
@SpringBootTest
public class NameChangeTest {
@Autowired
NameChangeRepository nameChangeRepository;
@Autowired
GeographicZoneRepository geographicZoneRepository;
private GeographicZone zone;
@BeforeEach
public void init() {
....
}
@Test
public void testNameChangeParameter() {
final NameChangePredicate predicate = new NameChangePredicate("", zone);
List<NameChange> list = nameChangeRepository.findAll();
Assert.assertEquals("There should be 4 NameChange in db", 4, list.size());
ValidationServiceResponse response = new ValidationServiceResponse();
response.setBookingClass("C");
Assert.assertTrue("Name change should be eligible", predicate.test(response));
}
}
但是在测试上下文中, predicate
的@Autowired
存储库为null
,可能是因为它是字段注入。 有没有办法将构造函数注入与其他参数一起使用?
试试这个
@Slf4j
public class NameChangePredicate implements ValidationPredicate {
String errorCode;
GeographicZone zone;
NameChangeRepository nameChangeRepository;
public NameChangePredicate(String errorCode, GeographicZone zone, NameChangeRepository nameChangeRepository) {
super();
this.errorCode = errorCode;
this.zone = zone;
this.nameChangeRepository = nameChangeRepository;
}
...
}
@ActiveProfiles("test")
@SpringBootTest
public class NameChangeTest {
@Autowired
NameChangeRepository nameChangeRepository;
....
@Test
public void testNameChangeParameter() {
final NameChangePredicate predicate = new NameChangePredicate("", zone, nameChangeRepository);
}
}
编辑:由于NameChangePredicate
不是 Spring @Component
本身,因此您需要从充当此类客户端的其他某个组件获取对存储库的引用。 如果您可以将类设计为组件,那么当您“在真实上下文中”运行它时,Spring 会自动将存储库注入构造函数,就像它在测试中自动装配一样。 但当然在这种情况下,您需要以某种方式摆脱构造函数参数errorCode
和zone
,这在本示例中似乎不太方便。
您在这里混合了两件事:Spring 配置和构造函数。
当您使用构造函数创建NameChangePredicate
的实例时,Spring 不工作且未对其进行初始化。
不确定如何更正您的示例,但看起来您的设计不太正确。 NameChangePredicate
做两件事:充当谓词并保存两个字段的逻辑。 我建议将这两个字段分开String errorCode; GeographicZone zone;
String errorCode; GeographicZone zone;
到一个单独的类,并把它注射在NameChangePredicate
以同样的方式为NameChangeRepository
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.