如何使用 REST Assured 为从提供者到消费者的 Pact 测试注入动态 ID
How to inject dynamic id for Pact test from provider to consumer using REST Assured
我需要使用 Pact 测试和 REST Assured 检查类型 /meeting/id 的 api。 id 可能会改变,我想在测试前创建一个项目并注入他们的 id 以覆盖设置为合同 url 路径一部分的内容,但不确定如何去做?
这是我的消费者:
@ExtendWith(PactConsumerTestExt.class)
public class PactConsumerTest {
Map<String, String> headers = new HashMap<>();
String storeMeetingPath = "/meeting/256";
@Pact(provider = VC, consumer = ED_UI)
public RequestResponsePact createPact(PactDslWithProvider builder) {
headers.put("Content-Type", "application/json");
headers.put("Accept", "application/json");
return builder
.given("A request to retrieve a meeting for a user")
.uponReceiving("A request to retrieve a meeting for a user")
.path(storeMeetingPath)
.method("GET")
.headers(headers)
.willRespondWith()
.body(new PactDslJsonBody()
.integerType("meetingId", 3)
.stringType("meetingTitle", "My title")
.stringType("meetingDescription", "My description"))
.status(200)
.toPact();
}
@Test
@PactTestFor(providerName = VC, port = "8080")
public void runTest() {
//Mock url
RestAssured.baseURI = "http://localhost:8080";
RequestSpecification rq = RestAssured
.given()
.headers(headers)
.when();
rq.get(storeMeetingPath);
}
}
这是我的提供商:
@Provider(VC)
@PactFolder("target/pacts")
public class PactProviderTest {
@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
void pactTestTemplate(PactVerificationContext context, HttpRequest request) {
request.addHeader("Authorization", AUTHORIZATION_TOKEN);
context.verifyInteraction();
}
@BeforeEach
void before(PactVerificationContext context) {
context.setTarget(new HttpsTestTarget(getBasePactEndpoint(), 443, "/"));
// Will create a meeting and retrieve the id from here but how to use this to overwrite what is there on the consumer?
getAuthorizationToken(UserType.TEACHER);
}
@State("A request to retrieve a meeting for a user")
public void sampleState() {
}
}
非常感谢。
我已经知道了这个问题的答案,在这里可能对其他人有帮助:
替换消费者合同中的这一行
.path(storeMeetingPath)
有
.pathFromProviderState("/meeting/${id}", "/meeting/500") // 500 is just a sample for the data type to be inferred. It can be any value from that same type.
这样我们就有了一个带有默认值的模板。
并在提供商端更改此设置
@State("A request to retrieve a meeting for a user")
public void sampleState() {
}
取而代之的是,它 returns 一个映射,可以为要注入的元素设置键和值。
@State("A request to retrieve a meeting for a user")
public Map sampleState() {
Map<String, Integer> map = new HashMap<>();
map.put("id", 391); // id for the meeting I want to retrieve.
return map;
}
辅助文档:
提供商:https://github.com/DiUS/pact-jvm/tree/master/provider/junit#returning-values-that-can-be-injected
我需要使用 Pact 测试和 REST Assured 检查类型 /meeting/id 的 api。 id 可能会改变,我想在测试前创建一个项目并注入他们的 id 以覆盖设置为合同 url 路径一部分的内容,但不确定如何去做?
这是我的消费者:
@ExtendWith(PactConsumerTestExt.class)
public class PactConsumerTest {
Map<String, String> headers = new HashMap<>();
String storeMeetingPath = "/meeting/256";
@Pact(provider = VC, consumer = ED_UI)
public RequestResponsePact createPact(PactDslWithProvider builder) {
headers.put("Content-Type", "application/json");
headers.put("Accept", "application/json");
return builder
.given("A request to retrieve a meeting for a user")
.uponReceiving("A request to retrieve a meeting for a user")
.path(storeMeetingPath)
.method("GET")
.headers(headers)
.willRespondWith()
.body(new PactDslJsonBody()
.integerType("meetingId", 3)
.stringType("meetingTitle", "My title")
.stringType("meetingDescription", "My description"))
.status(200)
.toPact();
}
@Test
@PactTestFor(providerName = VC, port = "8080")
public void runTest() {
//Mock url
RestAssured.baseURI = "http://localhost:8080";
RequestSpecification rq = RestAssured
.given()
.headers(headers)
.when();
rq.get(storeMeetingPath);
}
}
这是我的提供商:
@Provider(VC)
@PactFolder("target/pacts")
public class PactProviderTest {
@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
void pactTestTemplate(PactVerificationContext context, HttpRequest request) {
request.addHeader("Authorization", AUTHORIZATION_TOKEN);
context.verifyInteraction();
}
@BeforeEach
void before(PactVerificationContext context) {
context.setTarget(new HttpsTestTarget(getBasePactEndpoint(), 443, "/"));
// Will create a meeting and retrieve the id from here but how to use this to overwrite what is there on the consumer?
getAuthorizationToken(UserType.TEACHER);
}
@State("A request to retrieve a meeting for a user")
public void sampleState() {
}
}
非常感谢。
我已经知道了这个问题的答案,在这里可能对其他人有帮助:
替换消费者合同中的这一行
.path(storeMeetingPath)
有
.pathFromProviderState("/meeting/${id}", "/meeting/500") // 500 is just a sample for the data type to be inferred. It can be any value from that same type.
这样我们就有了一个带有默认值的模板。
并在提供商端更改此设置
@State("A request to retrieve a meeting for a user")
public void sampleState() {
}
取而代之的是,它 returns 一个映射,可以为要注入的元素设置键和值。
@State("A request to retrieve a meeting for a user")
public Map sampleState() {
Map<String, Integer> map = new HashMap<>();
map.put("id", 391); // id for the meeting I want to retrieve.
return map;
}
辅助文档:
提供商:https://github.com/DiUS/pact-jvm/tree/master/provider/junit#returning-values-that-can-be-injected