我找不到相关信息,但 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 有关。
您的问题与任何嵌套无关。
您调用
productRequestPort.find
,它会立即返回 CompletableFuture
并异步执行工作。
然后你立即检查结果,这当然失败了,因为你没有等待工作完成。
等待
CompletableFuture
完成,然后再检查期望。