为什么我们需要在 PACT 测试中进行单元测试?
Why do we need unit test in a PACT test?
最近,我熟悉了 PACT 测试。为每个交易方存根 producer/consumer 真是个很酷的主意。但是,我不明白一个核心原则。在客户端 PACT 测试中,生成 PACT json 文件的测试 - 为什么我需要启动测试服务器并用特定请求命中它?
例如我有生产者 A,我有消费者 B。生产者 A 有端点 getAllUsers,它将 return json 所有用户。
在消费者B中,我写了契约测试:
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "ProducerA", port = "1234")
public class ProducerAPactTest {
private static JSONArray body = new JSONArray("[ {'user_id': '1' }]");
@Pact(provider = "ProducerA", consumer = "ConsumerB")
RequestResponsePact createPact(PactDslWithProvider builder) {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", ContentType.APPLICATION_JSON.toString());
DslPart regionDsl = PactDslJsonArray.arrayEachLike()
.stringType("id", "1").closeObject().closeArray();
return builder.given("Normal state")
.uponReceiving("Get all users request")
.path("/users").method("GET").willRespondWith()
.status(200).headers(headers).body(regionDsl).toPact();
}
@Test
void runTest() {
// when
ResponseEntity<String> response = new RestTemplate()
.getForEntity(mockServer.getUrl() + "/users", String.class);
// then
assertThat(response.getStatusCode().value()).isEqualTo(200);
List<String> contentTypeHeaders = response.getHeaders().get("Content-Type");
String responseBody = response.getBody();
assertThat(contentTypeHeaders).isNotNull();
assertThat(responseBody).isNotNull();
assertThat(contentTypeHeaders.get(0)).isEqualTo(ContentType.APPLICATION_JSON.toString());
JSONAssert.assertEquals(responseBody, body, JSONCompareMode.LENIENT);
}
我用several tutorials写了pact测试。我在 Java 下开发,但我的问题一般适用于所有 Pact 测试。为什么我需要创建单元测试?对我来说,断言我收到的东西似乎完全没有意义,因为我已经在上面几行中定义了自己?我注意到所有契约消费者测试都遵循相同的模式。我错过了什么?
通常,被测 class 不仅仅是反序列化 JSON 主体。抱歉,这是一个 Ruby 示例而不是 java 示例,但这是一个将 JSON 文档转换为表示资源的模型的客户端 class 示例: https://github.com/pact-foundation/pact-ruby/blob/master/example/zoo-app/lib/zoo_app/animal_service_client.rb
我们在这里使用 pact test 来检查它如何处理不同的 http 响应(例如,它将 404 转换为 null)。如果您只是直接测试您的 HTTP 响应,那么除了与提供者建立合同之外,您的消费者代码根本没有太多价值。
最近,我熟悉了 PACT 测试。为每个交易方存根 producer/consumer 真是个很酷的主意。但是,我不明白一个核心原则。在客户端 PACT 测试中,生成 PACT json 文件的测试 - 为什么我需要启动测试服务器并用特定请求命中它?
例如我有生产者 A,我有消费者 B。生产者 A 有端点 getAllUsers,它将 return json 所有用户。 在消费者B中,我写了契约测试:
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "ProducerA", port = "1234")
public class ProducerAPactTest {
private static JSONArray body = new JSONArray("[ {'user_id': '1' }]");
@Pact(provider = "ProducerA", consumer = "ConsumerB")
RequestResponsePact createPact(PactDslWithProvider builder) {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", ContentType.APPLICATION_JSON.toString());
DslPart regionDsl = PactDslJsonArray.arrayEachLike()
.stringType("id", "1").closeObject().closeArray();
return builder.given("Normal state")
.uponReceiving("Get all users request")
.path("/users").method("GET").willRespondWith()
.status(200).headers(headers).body(regionDsl).toPact();
}
@Test
void runTest() {
// when
ResponseEntity<String> response = new RestTemplate()
.getForEntity(mockServer.getUrl() + "/users", String.class);
// then
assertThat(response.getStatusCode().value()).isEqualTo(200);
List<String> contentTypeHeaders = response.getHeaders().get("Content-Type");
String responseBody = response.getBody();
assertThat(contentTypeHeaders).isNotNull();
assertThat(responseBody).isNotNull();
assertThat(contentTypeHeaders.get(0)).isEqualTo(ContentType.APPLICATION_JSON.toString());
JSONAssert.assertEquals(responseBody, body, JSONCompareMode.LENIENT);
}
我用several tutorials写了pact测试。我在 Java 下开发,但我的问题一般适用于所有 Pact 测试。为什么我需要创建单元测试?对我来说,断言我收到的东西似乎完全没有意义,因为我已经在上面几行中定义了自己?我注意到所有契约消费者测试都遵循相同的模式。我错过了什么?
通常,被测 class 不仅仅是反序列化 JSON 主体。抱歉,这是一个 Ruby 示例而不是 java 示例,但这是一个将 JSON 文档转换为表示资源的模型的客户端 class 示例: https://github.com/pact-foundation/pact-ruby/blob/master/example/zoo-app/lib/zoo_app/animal_service_client.rb
我们在这里使用 pact test 来检查它如何处理不同的 http 响应(例如,它将 404 转换为 null)。如果您只是直接测试您的 HTTP 响应,那么除了与提供者建立合同之外,您的消费者代码根本没有太多价值。