如何使用REST Assured从提供者向消费者注入 Pact 测试的动态 id。

huangapple go评论65阅读模式
英文:

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, "/"));

        // 将在此创建一个会议并从中检索 ID,但如何使用它来覆盖消费者中的内容?
        getAuthorizationToken(UserType.TEACHER);
    }

    @State("A request to retrieve a meeting for a user")
    public void sampleState() {

    }
}

非常感谢。

英文:

I need to check an api of the type /meeting/id using Pact tests and REST Assured. The id may change and I'd like to create an item before the test and inject their id to overwrite what is set as part of the url path for the contract but not sure how to go about that please?

Here my consumer:

@ExtendWith(PactConsumerTestExt.class)
public class PactConsumerTest {
Map&lt;String, String&gt; headers = new HashMap&lt;&gt;();
String storeMeetingPath = &quot;/meeting/256&quot;;
@Pact(provider = VC, consumer = ED_UI)
public RequestResponsePact createPact(PactDslWithProvider builder) {
headers.put(&quot;Content-Type&quot;, &quot;application/json&quot;);
headers.put(&quot;Accept&quot;, &quot;application/json&quot;);
return builder
.given(&quot;A request to retrieve a meeting for a user&quot;)
.uponReceiving(&quot;A request to retrieve a meeting for a user&quot;)
.path(storeMeetingPath)
.method(&quot;GET&quot;)
.headers(headers)
.willRespondWith()
.body(new PactDslJsonBody()
.integerType(&quot;meetingId&quot;, 3)
.stringType(&quot;meetingTitle&quot;, &quot;My title&quot;)
.stringType(&quot;meetingDescription&quot;, &quot;My description&quot;))
.status(200)
.toPact();
}
@Test
@PactTestFor(providerName = VC, port = &quot;8080&quot;)
public void runTest() {
//Mock url
RestAssured.baseURI = &quot;http://localhost:8080&quot;;
RequestSpecification rq = RestAssured
.given()
.headers(headers)
.when();
rq.get(storeMeetingPath);
}
}

And here my provider:

@Provider(VC)
@PactFolder(&quot;target/pacts&quot;)
public class PactProviderTest {
@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
void pactTestTemplate(PactVerificationContext context, HttpRequest request) {
request.addHeader(&quot;Authorization&quot;, AUTHORIZATION_TOKEN);
context.verifyInteraction();
}
@BeforeEach
void before(PactVerificationContext context) {
context.setTarget(new HttpsTestTarget(getBasePactEndpoint(), 443, &quot;/&quot;));
// 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(&quot;A request to retrieve a meeting for a user&quot;)
public void sampleState() {
}
}

Thank you very much.

答案1

得分: 7

我已经学会了这个答案,如果对其他人有帮助的话,以下是答案:

在消费者合同中将这一行替换

.path(storeMeetingPath)

替换为

.pathFromProviderState("/meeting/${id}", "/meeting/500") // 500只是一个用于推断数据类型的示例。可以是该类型的任何值。

这样我们会有一个带有默认值的模板。

并且在提供者端更改如下

@State("A request to retrieve a meeting for a user")
public void sampleState() {

}

改为以下内容,以便返回一个映射,该映射将为要注入的元素设置键和值。

@State("A request to retrieve a meeting for a user")
public Map sampleState() {

    Map<String, Integer> map = new HashMap<>();
    map.put("id", 391); // 我想要检索的会议的id。

    return map;
}

辅助文档:

消费者:https://github.com/DiUS/pact-jvm/tree/master/consumer#having-values-injected-from-provider-state-callbacks

提供者:https://github.com/DiUS/pact-jvm/tree/master/provider/junit#returning-values-that-can-be-injected

英文:

I've learned the answer for this and here it is in case it may be helpful to anyone else:

Replace this line on the consumer contract

.path(storeMeetingPath)

With

.pathFromProviderState(&quot;/meeting/${id}&quot;, &quot;/meeting/500&quot;) // 500 is just a sample for the data type to be inferred. It can be any value from that same type.

So that we'd have a template with a default value.

And change this on provider side

@State(&quot;A request to retrieve a meeting for a user&quot;)
public void sampleState() {
} 

To have this instead, so that it returns a map which would set the key and value for the element to be injected.

@State(&quot;A request to retrieve a meeting for a user&quot;)
public Map sampleState() {
Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();
map.put(&quot;id&quot;, 391); // id for the meeting I want to retrieve.
return map;
}

Auxiliar documentation:

Consumer: https://github.com/DiUS/pact-jvm/tree/master/consumer#having-values-injected-from-provider-state-callbacks

Provider: https://github.com/DiUS/pact-jvm/tree/master/provider/junit#returning-values-that-can-be-injected

huangapple
  • 本文由 发表于 2020年9月18日 20:13:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/63955575.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定