首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Spring boot WebClient测试中模拟Spring5API

如何在Spring boot WebClient测试中模拟Spring5API
EN

Stack Overflow用户
提问于 2019-08-17 04:32:02
回答 1查看 5.1K关注 0票数 0

我有一个spring boot API,它内部调用了两个使用Spring WebClient的第三方API。我需要通过模拟两个API调用来端到端地测试我的API。如何创建一个MockWebServer来模拟我的DAOImpl类中的两个API调用。

我尝试配置MockWebServer来模拟WebClient,但它不起作用。

我的控制器

代码语言:javascript
运行
复制
@Autowired
private DemoDao dao;

@RequestMapping(value = "/webClient/testing", produces = { "application/json"}, method = RequestMethod.GET)
public ResponseEntity<String> webClientNonBlockingClient(@RequestHeader(value = "name_id", required = false) String nameId)
  {
    HttpStatus httpStatus = HttpStatus.OK;
    String userId = dao.getUserId(nameId);
    boolean userCheck = dao.checkUserAccess(nameId, userId);
    if (userCheck)
    {
      message = "check success";
    }
    else
    {
      message = "check failed";
      httpStatus = HttpStatus.UNAUTHORIZED;
    }
    return new ResponseEntity<>(message, httpStatus);
  }

DAO实现类

代码语言:javascript
运行
复制
@Repository
public class DemoDAOImpl
{

  @Autowired
  private WebClientFactory webClientFactory;

  public String getUserId(String nameId)
  {
    UserProfile profile = new UserProfile();
    Mono<UserProfile> response = null;
    try
    {
      String url = "/user/"+nameId+"/profile"
      WebClient client = webClientFactory.getWebClient();
      response = client.get().uri(builder -> 
      builder.path(url).build()).retrieve().bodyToMono(UserProfile.class);
      profile = response.block();
    }
    catch (WebClientResponseException e)
    {
      LOG.error("ResponseException {}", e);
    }
    return profile.getUserId();
  }
  
  public boolean userCheck(String nameId, String userId)
  {
    Mono<UserAccessResponse> result = null;
    try
    {
      WebClient client = webClientFactory.getWebClient();
      String url = "/user/"+nameId+"/check"
      result = client.get().uri(builder -> builder.path(url).queryParam("userId", userId).build())
          .retrieve().bodyToMono(UserAccessResponse.class);
      return result.block().isStatus();
    }
    catch (WebClientResponseException e)
    {
      LOG.error("APIexception {}", e);
    }
  }

webClient配置类

代码语言:javascript
运行
复制
@Configuration
public class WebClientFactory
{
  
  private String baseUrl = "https://abcd.com/v1/";
  
  private String apikey = "123456";
  
  public WebClientFactory()
  {
    // Default constructor
  }

  @Bean
  @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
  public WebClient getWebClient()
  {
    return WebClient
        .builder()
        .baseUrl(baseUrl)
        .defaultHeader(HttpHeaders.CONTENT_TYPE, 
 MediaType.APPLICATION_JSON_VALUE)
        .defaultHeader("apikey", apikey)
      .build();
  }  
}
}

我试着用下面的测试类模拟,但它不像预期的那样工作。我无法配置如何模拟2个外部api调用。

测试类

代码语言:javascript
运行
复制
@RunWith(SpringRunner.class)
@WebAppConfiguration()
@TestPropertySource("classpath:dev-manifest.yml")
@ContextConfiguration(classes = Application.class)
@SpringBootTest
public class WebClientMockTesting
{

  private static final Logger logger = LoggerFactory.getLogger(WebClientMockTesting.class);

  private static final String REQUEST_URI = "/webClient/testing";
  private static final String HEADER_KEY = "name_id";
  private static final String MOCK_USER_ID = "mockTest";

  private final MockWebServer mockWebServer = new MockWebServer();

  @Autowired
  private WebClientFactory webClientFactory;

  @Autowired
  private WebClient webClient;

  private MockMvc mockMvc;

  @Autowired
  private WebApplicationContext webApplicationContext;

  /**
   * build web application context
   */
  @Before
  public void setup()
  {
    try
    {
      mockWebServer.play(8084);
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    webClient = webClientFactory.getWebClient();
    webClient = WebClient.create(mockWebServer.getUrl("/").toString());
    this.mockMvc = webAppContextSetup(webApplicationContext).build();
  }

  @AfterEach
  void tearDown() throws IOException
  {
    mockWebServer.shutdown();
  }

  /**
   * Success scenario - GetFutureProjectedIncomeRIC
   */
  @Test
  public void testGetId()
  {
    try
    {
      mockWebServer.enqueue(
          new MockResponse()
                  .setResponseCode(200)
                  .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                  .setBody("{\"y\": \"value for y\", \"z\": 789}")
  );

      mockMvc.perform(get(REQUEST_URI).contentType(contentType).header(HEADER_KEY, MOCK_USER_ID))
          .andExpect(status().isOk());
    }
    catch (Exception e)
    {
      logger.error("test failed due to - {}", e.getStackTrace());
    }
  }
EN

回答 1

Stack Overflow用户

发布于 2019-08-18 11:22:05

到底是什么不起作用?在模拟web服务器中,您可以按照添加响应的顺序创建一个队列,一个接一个地发回响应。在您的代码中,使用以下命令添加一个响应

代码语言:javascript
运行
复制
mockWebServer.enqueue(

如果你需要从你的应用程序调用3次,你应该调用enqueue 3次。

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

https://stackoverflow.com/questions/57530788

复制
相关文章

相似问题

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