您的位置:首页 > 科技 > 能源 > 安徽网络技术服务推广_保定网站建设公司_做关键词优化的公司_网络广告类型

安徽网络技术服务推广_保定网站建设公司_做关键词优化的公司_网络广告类型

2024/12/22 23:05:18 来源:https://blog.csdn.net/adminmail/article/details/144509745  浏览:    关键词:安徽网络技术服务推广_保定网站建设公司_做关键词优化的公司_网络广告类型
安徽网络技术服务推广_保定网站建设公司_做关键词优化的公司_网络广告类型

模拟外部 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 获得以下日志

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com