我正在尝试测试我的应用程序中的一个简单谓词。此谓词使用存储库来检查某些数据,但当我对其进行测试时,存储库始终为 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));
}
}
但在测试上下文中,@Autowired
的 predicate
存储库是 null
,可能是因为它是字段注入。
有没有办法将构造函数注入与其他参数一起使用?
答案 0 :(得分:1)
试试这个
@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
,这在本示例中似乎不太方便。
答案 1 :(得分:-1)
您在这里混合了两件事:Spring 配置和构造函数。
当您使用构造函数创建 NameChangePredicate
的实例时,Spring 不工作且未对其进行初始化。
不确定如何更正您的示例,但看起来您的设计不太正确。 NameChangePredicate
做两件事:充当谓词并保存两个字段的逻辑。我建议将这两个字段 String errorCode; GeographicZone zone;
分开到一个单独的类中,并以与 NameChangePredicate
相同的方式将其注入 NameChangeRepository
。