首页 > 编程语言 >如何在 Spring Boot 应用程序中使用 WireMock 模拟外部 rest api 调用进行测试

如何在 Spring Boot 应用程序中使用 WireMock 模拟外部 rest api 调用进行测试

时间:2024-12-16 15:32:04浏览次数:5  
标签:WireMock skuCode Spring Boot api orderRequest public quantity

模拟外部 API 调用是集成或端到端测试中的常见做法,因为它允许开发人员将他们的代码与外部隔离。如果我们使用付费 API 并希望避免在测试时进行调用以节省资金,这也会有所帮助。

有两种方法可以模拟外部 API

  1. 使用 Mockito
  2. 使用 WireMock

在集成测试和端到端测试中,我更喜欢使用 WireMock,因为使用 WireMock 我们也可以测试 http 交互,而 mockito 将模拟整个 http 调用方法。

我们用于说明如何使用 WireMock 的场景有两个微服务,分别称为订单服务和库存服务。订单服务中的下单端点将对库存服务的库存端点进行 http 调用,以检查产品是否有库存,如果库存充足,则创建订单。

订单服务 — 控制器

@RestController 
@RequestMapping("/api/order") 
@RequiredArgsConstructor 
public  class  OrderController { 
   private  final OrderService orderService; 
   @PostMapping 
   @ResponseStatus(HttpStatus.CREATED) 
   public String placeOrder ( @RequestBody OrderRequest orderRequest) { 
       orderService.placeOrder(orderRequest); 
       return  "订单下达成功" ; 
   } 
}

OrderService — 服务

@RequiredArgsConstructor 
@Service 
public  class  OrderService { 


   private  final OrderRepository orderRepository; 
   private  final InventoryClient inventoryClient; 
   public  void  placeOrder (OrderRequest orderRequest) { 
       var  isProductInStock  = inventoryClient.isInStock(orderRequest.skuCode(), orderRequest.quantity()); 
       if (!isProductInStock) {
          throw new RuntimeException ( "产品缺货 " +orderRequest.skuCode()+ " " ); 
       } 
       Order  order  =  new  Order (); 
       order.setOrderNumber(UUID.randomUUID().toString()); 
       order.setPrice(orderRequest.price()); 
       order.setSkuCode(orderRequest.skuCode()); 
       order.setQuantity(orderRequest.quantity()); 
       orderRepository.save(order); 
   } 
}

库存服务——控制器

@RestController 
@RequestMapping("/api/inventory") 
@RequiredArgsConstructor 
public  class  InventoryController { 
   private  final InventoryService inventoryService; 


   @GetMapping 
   @ResponseStatus(HttpStatus.OK) 
   public  boolean  isInStock ( @RequestParam String skuCode,@RequestParam Integer quantile) { 
       return inventoryService.isInStock(skuCode,quantity); 
   } 
}

Order 微服务中用于对 Inventory 微服务进行 rest api 调用的 feign 客户端接口如下(但我们也可以使用 rest 模板或新的 rest 客户端来代替 Feign 进行此 http 调用)

@FeignClient(value = "inventory-service", url = "${inventory.url}")
public interface InventoryClient {
   @RequestMapping(method = RequestMethod.GET, value = "/api/inventory")
   boolean isInStock(@RequestParam String skuCode, @RequestParam Integer quantity);
}

设置和使用 WireMock 的步骤如下;

  1. 将 WireMock 依赖项添加到 pom.xml

在依赖项下添加以下内容

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
   <scope>test</scope>
</dependency>

最后在 pom.xml 的属性部分下添加 <spring-cloud.version>2023.0.1</spring-cloud.version> ,如下所示

<properties>
   <java.version>21</java.version>
   <spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>

如果你使用 gradle,请将以下代码添加到你的 build.gradle 文件中

ext {
   set('springCloudVersion', "2023.0.1")set('springCloudVersion', "2023.0.1")
}


dependencies {
   implementation 'org.springframework.boot:spring-boot-starter'
   testImplementation 'org.springframework.boot:spring-boot-starter-test'
   testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-stub-runner'
}


dependencyManagement {
   imports {
      mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
   }
}

2)使用@AutoConfigureWireMock注释spring boot测试

下一步是使用 @AutoConfigureWireMock 注释测试类

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 0)
class OrderServiceApplicationTests {}

端口 0 表示我们要求 spring boot 使用随机端口,以避免端口冲突

3)创建一个存根客户端类,并在其中创建一个用于api调用的存根方法

我们需要为存根方法创建一个单独的类,并在其中定义用于 API 调用方法的存根。我将创建一个存根方法来调用库存服务中的以下端点 /api/inventory。

public class InventoryClientStub {
   public static void stubInventoryCall(String skuCode, Integer quantity) {
       System.out.println("Stubbing inventory call for skuCode: " + skuCode + " and quantity: " + quantity);
       stubFor(get(urlEqualTo("/api/inventory?skuCode=" + skuCode + "&quantity=" + quantity))
               .willReturn(aResponse()
                       .withStatus(200)
                       .withHeader("Content-Type", "application/json")
                       .withBody("true")));
   }
}

每当 WireMock 收到与请求参数“/api/inventory?skuCode=” + skuCode + “&quantity=” + amount 匹配的 URL 时,WireMock 将返回状态代码为 200 且主体为 JSON 值的响应

4)在测试目录中创建一个资源文件夹,并在资源目录中创建“application.properties”文件

然后在 test/resources/application.properties 中添加带有 Wiremock 动态端口的 url

5)最后将存根添加到测试方法中

将 InventoryClientStub.stubInventoryCall(“iphone_15”, 1) 存根添加到测试方法

@Test 
void  shouldPlaceOrder () { 
   String  requestBody  =  """ 
         { 
             "skuCode":"iphone_15", 
             "price": 1000, 
             "quantity": 1 
         } 
         """ ; 


   InventoryClientStub.stubInventoryCall( "iphone_15" , 1 ); 


   var  responseBodyString  = RestAssured.given() 
         .contentType( "application/json" ) 
         .body(requestBody) 
         .when() 
         .post( "/api/order" ) 
         .then() 
         .statusCode( 201 ) 
         .extract() 
         .body().asString(); 
   assertThat(responseBodyString, Matchers.is( "订单下单成功" )); 
}

就是这样。运行测试时,你将从 WireMock 获得以下日志

标签:WireMock,skuCode,Spring,Boot,api,orderRequest,public,quantity
From: https://blog.csdn.net/adminmail/article/details/144509745

相关文章

  • Spring Cloud 面试锦集
    2020-SpringCloud面试锦集一:什么是微服务架构?二:Ribbon?1:负载均衡的核心组件?2:负载均衡算法?3:负载均衡的替换?4:Ribbon轮询负载均衡算法?三:Springcloud和springboot版本依赖关系四:eureka?五:openFeign六:Hystrix一:什么是微服务架构?微服务架构是一种架构模式,他提倡......
  • (附源码)springboot高校大学生就业管理信息系统-计算机毕设 33061
    高校大学生就业管理信息系统设计与实现摘 要在网络飞速发展的信息时代,各个行业都离不开信息的处理,在这种时代背景下,学校以学生的信息管理为导向,根据这点,为当前形势最重要的高校大学生就业管理信息设计一个就业信息管理系统就很有必要。高校大学生高校大学生就业管理信......
  • springboot毕设 疫情流调决策分析系统的设计与实现 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景近年来,全球范围内频繁爆发的疫情事件对公共卫生体系构成了严峻挑战。特别是在新冠疫情的冲击下,如何高效、准确地开展流行病学调查(简称“流调”),成为控......
  • springboot毕设 音乐推荐系统 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在数字化时代背景下,音乐作为一种重要的文化艺术形式,已经深入到了人们生活的每一个角落。随着音乐产业的蓬勃发展,音乐资源的数量呈现爆炸式增长,用户面......
  • 免费送源码:Java+springboot+MySQL springboot古诗文学习系统 计算机毕业设计原创定制
    摘 要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,古诗文学习系统当然也不能排除在外。古诗文学习系统是以实际运用为开发背景,运用软件工程原理和开发方法,采用springboot技术构建的一个管理系统。整个开发过......
  • 计算机毕业设计原创定制(免费送源码):Java+SpringBoot+MySQL SpringBoot医院人事工资管理
     摘 要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,医院当然也不例外。医院人事工资管理系统是以实际运用为开发背景,运用软件工程原理和开发方法,采用Java技术构建的一个管理系统。整个开发过程首先对软件系......
  • 【计算机毕业设计选题推荐】基于springboot的鹿幸公司员工在线餐饮管理系统的设计与实
    ✍✍计算机毕设编程指导师**⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流!⚡⚡Java、Python、小程序、大数据实战项目集⚡⚡文末获取......
  • 【计算机毕业设计选题推荐】基于springboot的流浪猫狗救助系统的设计与实现 【附源码+
    ✍✍计算机毕设编程指导师**⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流!⚡⚡Java、Python、小程序、大数据实战项目集⚡⚡文末获取......
  • 基于SpringBoot的响应式技术博客-毕业设计源码28629
    目录摘要1绪论1.1选题背景与意义1.2国内外研究现状1.3本课题主要工作1.4论文结构与章节安排2系统分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3法律可行性分析2.2系统流程分析2.2.1数据新增流程2.2.2 数据删除流程2.3 系统功能分......
  • springboot安徽省古陶瓷博物馆宣传平台-毕业设计源码28633
    目 录第1章引 言1.1选题背景1.2研究现状1.3论文结构安排第2章系统的需求分析2.1系统可行性分析2.1.1技术方面可行性分析2.1.2经济方面可行性分析2.1.3法律方面可行性分析2.1.4操作方面可行性分析2.2系统功能需求分析2.3系统性......