Spring测试:客户端应用程序测试

https://docs.spring.io/spring-framework/reference/testing/spring-mvc-test-client.html

你可以使用客户端测试来测试内部使用RestTemplate的代码。这个测试的主要思想是声明预期的请求,并提供“模拟”响应,这样你就可以专注于单独测试代码(即无需运行服务器)。以下示例展示了如何进行这种测试:

RestTemplate restTemplate = new RestTemplate();

MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess());

// Test code that uses the above RestTemplate ...

mockServer.verify();

在前面的示例中,MockRestServiceServer(客户端REST测试的核心类)通过配置RestTemplate使用一个自定义的ClientHttpRequestFactory,该工厂将实际的请求与预期进行比较,并返回“模拟”响应。在这个例子中,我们预期一个请求会发送到/greeting,并希望返回一个状态码为200的响应,内容类型为text/plain。我们可以根据需要定义其他预期的请求和模拟响应。当我们定义了预期的请求和模拟响应后,RestTemplate就可以像平常一样在客户端代码中使用。在测试结束时,可以使用mockServer.verify()来验证所有的预期是否都已满足。

默认情况下,请求是按照声明的预期顺序来预期的。在构建服务器时,你可以设置ignoreExpectOrder选项,在这种情况下,所有的预期都会按顺序检查以找到一个与给定请求相匹配的预期。这意味着请求可以以任何顺序到来。以下示例使用了ignoreExpectOrder

server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();

即使默认情况下请求是无序的,每个请求也只允许运行一次。expect方法提供了一个重载变体,它接受一个ExpectedCount参数,用于指定计数范围(例如,oncemanyTimesmaxminbetween等)。以下示例使用了times

RestTemplate restTemplate = new RestTemplate();

MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess());
mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess());

// ...

mockServer.verify();

请注意,当未设置ignoreExpectOrder(这是默认值)时,请求的期望顺序就是声明的顺序。但这种顺序仅适用于任何期望请求中的第一个。例如,如果期望"/something"出现两次,然后期望"/somewhere"出现三次,那么必须在对"/somewhere"发出请求之前先对"/something"发出请求,但是除此之外,后续的"/something"和"/somewhere"请求可以在任何时间发出。

作为上述所有方法的替代方案,客户端测试支持还提供了一个ClientHttpRequestFactory的实现,你可以将其配置到RestTemplate中,并将其绑定到一个MockMvc实例。这样,你可以使用实际的服务器端逻辑来处理请求,而无需运行服务器。以下示例展示了如何操作:

MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
this.restTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(mockMvc));

// Test code that uses the above RestTemplate ...

在某些情况下,可能有必要实际调用远程服务而不是模拟响应。以下示例展示了如何通过ExecutingResponseCreator来实现这一点:

RestTemplate restTemplate = new RestTemplate();

// Create ExecutingResponseCreator with the original request factory
ExecutingResponseCreator withActualResponse = new ExecutingResponseCreator(restTemplate.getRequestFactory());

MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/profile")).andRespond(withSuccess());
mockServer.expect(requestTo("/quoteOfTheDay")).andRespond(withActualResponse);

// Test code that uses the above RestTemplate ...

mockServer.verify();

在前面的例子中,我们在使用MockRestServiceServer替换RestTemplate中的ClientHttpRequestFactory之前,使用它来创建了ExecutingResponseCreator。然后,我们为两种响应定义了期望:

  • 一个针对/profile端点的桩 200响应(不会执行实际请求)
  • 一个通过调用/quoteOfTheDay端点获得的响应

在第二种情况下,请求是通过之前捕获的ClientHttpRequestFactory执行的。这会生成一个响应,该响应可能来自实际的远程服务器,具体取决于RestTemplate的原始配置。

静态导入

与服务器端测试一样,客户端测试的流畅API也需要一些静态导入。通过搜索MockRest*可以轻松找到它们。Eclipse用户应该在Eclipse偏好设置下的Java → Editor → Content Assist → Favorites中将MockRestRequestMatchers.*MockRestResponseCreators.*添加为“favorite static members”。这样,在键入静态方法名的第一个字符后,就可以使用内容辅助了。其他IDE(如IntelliJ)可能不需要任何额外配置。

  • 16
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值