如何在 spring-boot 中使用 resttemplate 模拟调用另一个服务的服务?
How to mock a service calling another service using resttemplate in spring-boot?
各位专家下午好,
我有一个要求,我将调用 3 个 REST API 的顺序调用作为单个客户端调用 GET /offers 的一部分,以检索百货商店不同通道中每个产品的可用报价以下
- 获取百货商店的所有过道 /aisels
- 获取一个过道/aisles/{aisleID}/products中的所有产品
获取产品/product/{productId/offers
的所有报价
要使用 RestTemplate 交换方法从我的 @Service
class 执行此操作:
ResponseEntity 过道= restTemplate.exchange(url,
HttpMethod.GET, requestEntity, Aisles.class);
然后在循环中检索每个 aisleId
并调用第二个 API 以获取 Products
ResponseEntity<Products> products= restTemplate.exchange(url,
HttpMethod.GET, requestEntity, Products.class);
然后在循环中检索每个 productId
并调用第 3 个 API 来获取报价
最后整理所有回复以将报价列表发送给客户。
现在,我是编写 JUnit 的 mockito 框架的新手。我的服务 class 有一个名为 retrieveAllOffers() 的方法,其中我有上面的 3 种交换方法。
我想知道如何在我的 Junit 中模拟这 3 个调用以获得成功的响应场景。
非常感谢您的帮助。
您可以只模拟服务的响应,而不是模拟其余模板。为此,您可以使用 Wiremock (http://wiremock.org/),它提供了一个 api 来存根对特定 URL 的调用并模拟它们对您喜欢的任何响应并验证它们是否被调用。
对于您的情况,您需要 3 个存根,每个交换一个。例如对于这个方法
restTemplate.exchange(url, GET, requestEntity, Products.class);
你提供的存根看起来像
stubFor(get(urlEqualTo("yourUrl"))
.willReturn(aResponse()
.withStatus(200)
.withBody(new ObjectMapper().writeValueAsString(yourResponseObject)
.withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE))
请注意,您的 url 需要将其服务器指向 wiremock 所在的位置 运行(如果您使用 java 依赖项和 junit 规则,它将是 localhost:wiremockPort)
设置非常简单,因为您需要向测试添加一个规则
@Rule public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort());
在这里查看规则 http://wiremock.org/docs/configuration/
的配置
最后你验证你的存根是用
调用的
verify(getRequestedFor(urlEqualTo("/yourUrl"))
.withRequestBody(equalTo(new ObjectMapper().writeValueAsString(theObjectThatShouldBePosted))));
希望对您有所帮助!
各位专家下午好,
我有一个要求,我将调用 3 个 REST API 的顺序调用作为单个客户端调用 GET /offers 的一部分,以检索百货商店不同通道中每个产品的可用报价以下
- 获取百货商店的所有过道 /aisels
- 获取一个过道/aisles/{aisleID}/products中的所有产品
获取产品/product/{productId/offers
的所有报价要使用 RestTemplate 交换方法从我的
@Service
class 执行此操作:ResponseEntity 过道= restTemplate.exchange(url, HttpMethod.GET, requestEntity, Aisles.class);
然后在循环中检索每个 aisleId
并调用第二个 API 以获取 Products
ResponseEntity<Products> products= restTemplate.exchange(url,
HttpMethod.GET, requestEntity, Products.class);
然后在循环中检索每个 productId
并调用第 3 个 API 来获取报价
最后整理所有回复以将报价列表发送给客户。
现在,我是编写 JUnit 的 mockito 框架的新手。我的服务 class 有一个名为 retrieveAllOffers() 的方法,其中我有上面的 3 种交换方法。
我想知道如何在我的 Junit 中模拟这 3 个调用以获得成功的响应场景。
非常感谢您的帮助。
您可以只模拟服务的响应,而不是模拟其余模板。为此,您可以使用 Wiremock (http://wiremock.org/),它提供了一个 api 来存根对特定 URL 的调用并模拟它们对您喜欢的任何响应并验证它们是否被调用。
对于您的情况,您需要 3 个存根,每个交换一个。例如对于这个方法
restTemplate.exchange(url, GET, requestEntity, Products.class);
你提供的存根看起来像
stubFor(get(urlEqualTo("yourUrl"))
.willReturn(aResponse()
.withStatus(200)
.withBody(new ObjectMapper().writeValueAsString(yourResponseObject)
.withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE))
请注意,您的 url 需要将其服务器指向 wiremock 所在的位置 运行(如果您使用 java 依赖项和 junit 规则,它将是 localhost:wiremockPort)
设置非常简单,因为您需要向测试添加一个规则
@Rule public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort());
在这里查看规则 http://wiremock.org/docs/configuration/
最后你验证你的存根是用
调用的verify(getRequestedFor(urlEqualTo("/yourUrl"))
.withRequestBody(equalTo(new ObjectMapper().writeValueAsString(theObjectThatShouldBePosted))));
希望对您有所帮助!