在 class 构造上覆盖自动装配对象
Overiding a Autowired object on class construction
我有一个使用自动装配属性对象的 class。这些属性需要一些配置才能使我的通信正常工作。在我的单元测试中,我写了一个通信应该失败的场景,方法是重写 class 构造函数中的属性对象,如下所示:
public class TokenRetriever{
@Autowired
private TokenRepository repository;
@Autowired
private Properties properties;
//custom constructor for me to override the properties
public TokenRetriever(Properties properties){
this.properties = properties;
}
private Token retrieveToken() {
Token token = null;
try {
//communication to an endpoint using properties
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return token;
}
public Token getAccessToken() throws NullAccessToken {
Token token;
token = repository.findTop1ByExpiresAtGreaterThanOrderByExpiresAtDesc(LocalDateTime.now());
if (token == null) token = this.retrieveToken();
if (token == null) throw new NullAccessToken("Could not retrieve any tokens");
return token;
}
}
这是我的单元测试:
@Test
void ShouldNotRetrieveAToken() {
//this is the property i'm changing in order to force a failure
properties.setClientId("dummy");
tokenRetriever = new TokenRetriever(properties);
Exception exception = assertThrows(NullAccessToken.class,
() ->
tokenRetriever.getAccessToken()
);
String expectedMessage = "Could not retrieve any tokens";
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));
}
当我 运行 单元测试时,它工作得很好。但是,当我构建项目时,这失败了,因为没有抛出错误。我认为这是因为覆盖不起作用。我是 spring boot 和 junits 的新手,所以这可能与 spring 生命周期有关。我怎样才能完成属性覆盖以使我的 junit 通过?
您正在混合使用构造函数和字段注入。
建议尽可能使用构造函数注入。您也不需要注释。
private final TokenRepository repository;
private final Properties properties;
public TokenRetriever(TokenRepository repository, Properties properties){
this.repository = repository;
this.properties = properties;
}
构造函数注入仅在对象创建时进行注入。
如果你想用不同的 属性 对象创建另一个对象,你必须使用基于 Setter 的依赖注入。
有基于 setter 的注入文档 https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-setter-injection
我有一个使用自动装配属性对象的 class。这些属性需要一些配置才能使我的通信正常工作。在我的单元测试中,我写了一个通信应该失败的场景,方法是重写 class 构造函数中的属性对象,如下所示:
public class TokenRetriever{
@Autowired
private TokenRepository repository;
@Autowired
private Properties properties;
//custom constructor for me to override the properties
public TokenRetriever(Properties properties){
this.properties = properties;
}
private Token retrieveToken() {
Token token = null;
try {
//communication to an endpoint using properties
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return token;
}
public Token getAccessToken() throws NullAccessToken {
Token token;
token = repository.findTop1ByExpiresAtGreaterThanOrderByExpiresAtDesc(LocalDateTime.now());
if (token == null) token = this.retrieveToken();
if (token == null) throw new NullAccessToken("Could not retrieve any tokens");
return token;
}
}
这是我的单元测试:
@Test
void ShouldNotRetrieveAToken() {
//this is the property i'm changing in order to force a failure
properties.setClientId("dummy");
tokenRetriever = new TokenRetriever(properties);
Exception exception = assertThrows(NullAccessToken.class,
() ->
tokenRetriever.getAccessToken()
);
String expectedMessage = "Could not retrieve any tokens";
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));
}
当我 运行 单元测试时,它工作得很好。但是,当我构建项目时,这失败了,因为没有抛出错误。我认为这是因为覆盖不起作用。我是 spring boot 和 junits 的新手,所以这可能与 spring 生命周期有关。我怎样才能完成属性覆盖以使我的 junit 通过?
您正在混合使用构造函数和字段注入。
建议尽可能使用构造函数注入。您也不需要注释。
private final TokenRepository repository;
private final Properties properties;
public TokenRetriever(TokenRepository repository, Properties properties){
this.repository = repository;
this.properties = properties;
}
构造函数注入仅在对象创建时进行注入。 如果你想用不同的 属性 对象创建另一个对象,你必须使用基于 Setter 的依赖注入。 有基于 setter 的注入文档 https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-setter-injection