在 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