【问题标题】:How to inject dynamic id for Pact test from provider to consumer using REST Assured如何使用 REST Assured 将 Pact 测试的动态 id 从提供者注入到消费者
【发布时间】:2021-01-05 09:10:40
【问题描述】:

我需要使用 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() {

}

}

非常感谢。

【问题讨论】:

    标签: java pact pact-jvm


    【解决方案1】:

    我已经知道了这个问题的答案,如果它可能对其他人有所帮助:

    替换消费者合同上的这一行

    .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() {
    
    } 
    

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

    @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/consumer#having-values-injected-from-provider-state-callbacks

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

    【讨论】:

    • 嗨弗朗西斯莱尼!您能否分享一下您是如何解决在您的消费者中成功运行 runTest() 的问题的?在原始问题中,您使用了 RestAssured 的以下路径:“/meeting/256”。使用建议的解决方案,新路径是“/meeting/${id}”。 HTTP 客户端需要解析路径才能对模拟服务器执行 GET。使用模板的默认值会生成 500 状态代码作为响应。提前致谢!
    • 嗨,你在这里注入了 id @State("A request to retrieve a meeting for a user") public Map sampleState() { Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;(); map.put("id", 391); return map; } 所以它解析为一个有效的路径。
    • 是的,这适用于提供程序测试。消费者测试呢? IE。 rq.get(storeMeetingPath); 来自 runTest()?您可以在消费者中声明@State,但 RestAssure 将无法使用 pathParam 500 甚至 /meeting/500 解析 storeMeetingPath=/meeting/${id}、/meeting/{id}。
    • 而不是这个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) .toPact();
    • 你有这个return builder .given("A request to retrieve a meeting for a user") .uponReceiving("A request to retrieve a meeting for a user") .pathFromProviderState(storeMeetingPathWithAppendedId, "your path with appended id") .method("GET") .headers(headers) .status(200) .toPact();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-20
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    相关资源
    最近更新 更多