当前位置: 首页 > 知识库问答 >
问题:

Spring Boot@Async annotation和MockRestServiceServer

郭子航
2023-03-14

我使用Spring Boot 2.0.6和Java10。我做了以下服务,仅使用RestTemboard访问外部Restapi。

@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 GET”http://localthost...“过度”

所以@Async似乎是在模仿MockerServerService响应...此外,如果我评论了@Async注释,一切都很好,我得到了所有测试绿色。

提前感谢您的意见。

更新:

根据@M.Deinum的评论。我从服务中删除了CompletableFuture,但我仍然得到同样的例外。

共有1个答案

池俊茂
2023-03-14

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

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

对该方法的调用将始终以null响应。由于您的测试运行得非常快,所有内容都已被删除(或正在被删除),因此预计不会再进行调用。

要修复,请修复方法签名并返回Future

@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());
}

现在,调用代码知道返回的未来以及Spring异步代码。现在,在测试中,您可以对返回的值调用get(如果出现故障,可能会超时以接收错误)。检查结果。

 类似资料:
  • 当我只保留一个主键--无论是CFO_ID还是LAST_UPDATE_DTS,并完全删除Idclass时,它工作得非常好。这让我认为idclass有问题,但我找不到任何问题。有人能帮忙吗?

  • 我正在寻找集成Hazelcast到我的应用程序... 我的要求是将所有数据加载到缓存并从缓存中提取。。 我有两个选择。 1) Hazelcast IMap 2)因为我使用的是Spring启动,所以我可以使用(@Cacheable/@CacheEvict)。 我能得到一些建议吗... 提前谢谢你。。

  • 我有教育问题: 存在具有windows server 2003(AD)的虚拟机,其中包含用户及其密码。已建立与机器的连接(ip:192.168.56.101:389)。 Web应用程序的目的是使用户能够在AD中更改他的密码。 问题:无法配置到windws server 2003的连接。 我从这个教程开始https://spring.io/guides/gs/authenticating-ldap/

  • 我正在尝试将缓存添加到springboot应用程序中,并且我遇到了一个问题,即在启动期间抛出org.ehcache.jsr107.MultiCacheException异常。 我使用的是以下(全部通过Maven pom文件加载):Springboot 1.5.5,Ehcache 3.3.1,Javax cache 1.0.0 我的SpringBootApplication看起来像这样: 我有一个包

  • 我在我的模型中使用LocalDateTime,在包括LocalDateTimeDeserializer之后,将bean字段转换为 包括 属性在SpringBoot的应用程序中。属性文件,应用程序最终能够反序列化JSON并正确显示如下内容:, 但是,当我进行测试时,它会忽略WRITE_DATES_AS_TIMESTAMPS标志,我猜它会为上面相同的字符串日期生成一个输出, 请注意,在测试资源文件夹中

  • controller.java UserServiceImpl.java 我得到了这个错误 应用程序启动失败 描述: 我使用的SpringBoot版本:2.1.0.发行版

  • 我正在尝试使用两个数据源与我的SpringBoot应用程序,但无法获得第二个数据源自动连接。我尝试过很多事情,但这是我最接近的一次: 我的Yaml文件: 这是我到目前为止最接近的一次。我之所以说它是最接近的,是因为如果我删除@qualifier,那么我的两个dao方法实际上都可以工作,假设SECOND_SELECT语句对于我的DB1是有效的SQL语句。当我为非主datasouce输入@Qualif