我使用SpringBoot2.0.6和Java10。我做了以下服务,只使用RestTemplate访问外部rest。
@Service
@Slf4j
public class DbApiClientImpl implements DbApiClient {
private final String URL_DELIMITER = "/";
private RestTemplate restTemplate;
private String url;
public DbApiClientImpl(
RestTemplateBuilder restTemplate,
@Value("${dbapi.namespace}") String namespace,
@Value("${dbapi.url}") String uri,
@Value("${dbapi.username}") String username,
@Value("${dbapi.password}") String password) {
this.restTemplate = restTemplate.basicAuthorization(username,
password).build();
this.url = namespace.concat(uri);
}
@Override
@Async("asyncExecutor")
public Merchant fetchMerchant(String id) {
ResponseEntity<Merchant> response =
restTemplate.getForEntity(url.concat(URL_DELIMITER).concat(id),
Merchant.class);
return response.getBody();
}
}以及使用MockeRestServiceServer进行的以下测试:
@RunWith(SpringRunner.class)
@RestClientTest(value = {DbApiClient.class})
public class DbApiClientTest {
private static final String TEST_NAME = "test";
private static final String TEST_NAME_BAD_REQUEST = "test-
1";
private static final String TEST_NAME_SERVER_ERROR =
"test-2";
@Autowired DbApiClient dbApiClient;
@Value("${dbapi.namespace}")
private String namespace;
@Value("${dbapi.url}")
private String dbApiUrl;
@Autowired private MockRestServiceServer mockServer;
@Autowired private ObjectMapper objectMapper;
@Test
public void test() throws
JsonProcessingException, IOException {
Merchant mockMerchantSpec = populateFakeMerchant();
String jsonResponse =
objectMapper.writeValueAsString(mockMerchantSpec);
mockServer
.expect(manyTimes(),
requestTo(dbApiUrl.concat("/").concat(TEST_NAME)))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(jsonResponse,
MediaType.APPLICATION_JSON));
assertNotNull(dbApiClient.fetchMerchant(TEST_NAME));
}问题是,当我运行测试“没有进一步的请求预期HTTP .http://localthost.”时,我得到了以下异常
所以看来@异步是在轮询MockerServerService响应..。另外,如果我注释了@异步注释,那么一切都很好,并且我得到了所有的测试绿色。
谢谢您的评论。
更新:
如@M.Deinum的评论所示。我从服务中删除了CompletableFuture,但仍然得到了相同的异常。
发布于 2018-11-24 18:25:51
问题在于你的代码而不是你的测试。
如果您阅读AsyncExecutionInterceptor的文档(AsyncExecutionInterceptor),您将看到只支持作为返回类型的void或Future。您正在返回一个普通对象,它在内部被视为void。
对该方法的调用将始终使用null进行响应。当您的测试运行得非常快时,所有的东西都已经被撕毁(或者正在被撕毁),不会再有更多的调用了。
若要修复,请修复您的方法签名并返回一个Future<Merchant>,以便您可以阻止并等待结果。
@Override
@Async("asyncExecutor")
public Future<Merchant> fetchMerchant(String id) {
ResponseEntity<Merchant> response =
restTemplate.getForEntity(url.concat(URL_DELIMITER).concat(id),
Merchant.class);
return CompletableFuture.completedFuture(response.getBody());
}现在,您的调用代码知道了返回的Future以及Spring异步代码。现在,在您的测试中,您现在可以对返回的值调用get (如果发生故障,可以使用超时来接收错误)。检查结果。
https://stackoverflow.com/questions/53437218
复制相似问题