首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring @异步注释和MockRestServiceServer

Spring @异步注释和MockRestServiceServer
EN

Stack Overflow用户
提问于 2018-11-22 19:41:35
回答 1查看 648关注 0票数 1

我使用SpringBoot2.0.6和Java10。我做了以下服务,只使用RestTemplate访问外部rest。

代码语言:javascript
复制
@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进行的以下测试:

代码语言:javascript
复制
@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,但仍然得到了相同的异常。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-24 18:25:51

问题在于你的代码而不是你的测试。

如果您阅读AsyncExecutionInterceptor的文档(AsyncExecutionInterceptor),您将看到只支持作为返回类型的voidFuture。您正在返回一个普通对象,它在内部被视为void

对该方法的调用将始终使用null进行响应。当您的测试运行得非常快时,所有的东西都已经被撕毁(或者正在被撕毁),不会再有更多的调用了。

若要修复,请修复您的方法签名并返回一个Future<Merchant>,以便您可以阻止并等待结果。

代码语言:javascript
复制
@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 (如果发生故障,可以使用超时来接收错误)。检查结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53437218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档