【问题标题】:Overiding a Autowired object on class construction在类构造上覆盖 Autowired 对象
【发布时间】:2021-05-17 15:17:49
【问题描述】:

我有一个使用自动装配属性对象的类。这些属性需要一些配置才能使我的通信正常工作。在我的单元测试中,我通过覆盖类构造函数中的属性对象,编写了一个通信失败的场景,如下所示:

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通过,我怎样才能完成属性覆盖?

【问题讨论】:

    标签: java spring spring-boot junit


    【解决方案1】:

    构造函数注入仅在对象创建时进行注入。 如果要创建具有不同属性对象的另一个对象,则必须使用基于 Setter 的依赖注入。 有基于setter的注入文档https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-setter-injection

    【讨论】:

    【解决方案2】:

    您正在混合构造函数和字段注入。

    建议尽可能使用构造函数注入。您也不需要注释。

    private final TokenRepository repository;
    private final Properties properties;
    
    public TokenRetriever(TokenRepository repository, Properties properties){
        this.repository = repository;
        this.properties = properties;
    }
    

    【讨论】:

    • 通过这样做,我在其他自动装配字段上获得了 NPE。我没有上传整个代码来专注于手头的问题。问题现已编辑。
    • 请注意,当我使用以下方法实例化 TokenRetriever 时,tokenRepository 为空:TokenRetriever tokenRetriever = new TokenRetriever(properties);
    • 我忽略了另一个依赖项。只需对所有依赖项使用构造函数注入。我已经更新了我的分析器
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 2017-10-08
    • 2021-01-17
    • 2017-04-06
    • 1970-01-01
    相关资源
    最近更新 更多