Spock Mock 无法在 lambda 函数内工作

问题描述 投票:0回答:1

我找不到相关信息,但 Spock 模拟似乎无法在我的 lambda 函数内工作。我试过了:

    RestTemplateAdapter restTemplateAdapter = Mock(RestTemplateAdapter)
    int maxRety = 5
    String baseUrl = "baseUrl"
    ProductRequestPort productRequestPort = new ProductRequestAdapter( restTemplateAdapter, baseUrl, maxRety)

        def "should throw erro"() {
        given:
        String errorMsg = "Error test message"
        Long customerCode = 1234L

        when:
        productRequestPort.find(customerCode)
        then:

        maxRety * restTemplateAdapter.exchange(_, _, _, _) >> { throw new RuntimeException(errorMsg) }
        GatewayException error = thrown(GatewayException.class)
        error.getMessage() == "Error when trying to get products."

    }

我试图模拟的方法:

    public CompletableFuture<ProductListResponse> find(Long customerCode) {
    String url = BASE_URL + customerCode;
    HttpEntity<?> entity = new HttpEntity<>();

    return CompletableFuture.supplyAsync(() -> {
        return retrieveProductListResponse(customerCode, url, entity);
    });
}

    private ProductListResponse retrieveProductListResponse(Long customerCode, String url, HttpEntity<?> entity) {
    int attempt = 0;
    while (attempt < MAX_RETRIES) {
        try {
            ResponseEntity<ProductListResponse> response = restTemplateAdapter.exchange(
                    url,
                    HttpMethod.GET,
                    entity,
                    ProductListResponse.class
            );
            return response.getBody();
        } catch (Exception e) {
            attempt++;
        }
    }
    throw new GatewayException(ERROR_GETTING_PRODUCTS);}

我从测试执行中收到:

    Too few invocations for:

maxRety * restTemplateAdapter.exchange(_, _, _, _) >> { throw new RuntimeException(errorMsg) }   (1 invocation)

Mock 只是返回一个“null”作为来自restTemplateAdapter 的响应。

我将 RestTemplate 类放入适配器中,因为我认为 Spock 无法正确模拟它,但即使使用该接口,错误仍然存在。如果我向公众开放方法 retrieveProductListResponse 并从测试中调用它,spock 就能够模拟它。因此,我怀疑该问题可能与 CompletableFuture 中的 lambda 有关。

java spring-boot spock
1个回答
0
投票

您的问题与任何嵌套无关。

您调用

productRequestPort.find
,它会立即返回
CompletableFuture
并异步执行工作。

然后你立即检查结果,这当然失败了,因为你没有等待工作完成。

等待

CompletableFuture
完成,然后再检查期望。

© www.soinside.com 2019 - 2024. All rights reserved.