Is there an V4 Pact example available like this fo...
# pact-jvm
m
Is there an V4 Pact example available like this for V3: https://github.com/pact-foundation/pact-jvm/blob/master/consumer/junit5/src/test/java/au/com/dius/pact/consumer/junit5/AsyncMessageTest.java ? Is there a wat to make a builder.toPact() give a MassagePact V4? Seems there is only a V4Pact and no V4MessagePact
1
u
V4 pacts can have both message and HTTP interactions. There is no separate V4MessagePact
m
That i know. My Question realy is what in the V3 example needs to change so its a V4 example. I can't just change out Message with V4Pact can i? This just doesnt work:
Copy code
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "wg-sector-service", providerType = ProviderType.ASYNCH)
class ParitairComiteChangedEventContractTest {

    public static final String PARITAIR_COMITE_ID = "01234567890123456789012345678901";

    @Pact(consumer = "dimona-service")
    V4Pact paritairComiteChangedEventPact(MessagePactBuilder builder) {
        PactDslJsonBody body = new PactDslJsonBody();
        body.stringMatcher("id", "^[a-zA-Z0-9]{32}$", PARITAIR_COMITE_ID);

        Map<String, Object> metadata = new HashMap<>();
        metadata.put("Content-Type", "application/json");

        return builder
                .expectsToReceive("valid ParitairComiteChangedEvent from wg-sector-service")
                .withMetadata(metadata)
                .withContent(body)
                .toPact(V4Pact.class);
    }


    @Test
    @PactTestFor(pactMethod = "paritairComiteChangedEventPact")
    void test(List<Message> messages) {
        assertThat(new String(messages.get(0).contentsAsBytes()), is("{\"id\":\"" + PARITAIR_COMITE_ID + "\"}"));
    }
}
This works but then it is V3 and i want a V4 Pact:
Copy code
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "wg-sector-service", providerType = ProviderType.ASYNCH, pactVersion = PactSpecVersion.V3)
class ParitairComiteChangedEventContractTest {

    public static final String PARITAIR_COMITE_ID = "01234567890123456789012345678901";

    @Pact(consumer = "dimona-service")
    MessagePact paritairComiteChangedEventPact(MessagePactBuilder builder) {
        PactDslJsonBody body = new PactDslJsonBody();
        body.stringMatcher("id", "^[a-zA-Z0-9]{32}$", PARITAIR_COMITE_ID);

        Map<String, Object> metadata = new HashMap<>();
        metadata.put("Content-Type", "application/json");

        return builder
                .expectsToReceive("valid ParitairComiteChangedEvent from wg-sector-service")
                .withMetadata(metadata)
                .withContent(body)
                .toPact();
    }


    @Test
    @PactTestFor(pactMethod = "paritairComiteChangedEventPact")
    void test(List<Message> messages) {
        assertThat(new String(messages.get(0).contentsAsBytes()), is("{\"id\":\"" + PARITAIR_COMITE_ID + "\"}"));
    }
}
@uglyog is there a way to generate a V4 pact with MessagePactBuilder. My rest pacts are V4 so i need these tests to be V4 as well or they dont merge and i get errors. It would be a shame to downgrade my rest pacts from V4 to V3 because my async test cant be V4.
I found a solution
Copy code
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "wg-sector-service", providerType = ProviderType.ASYNCH)
class ParitairComiteChangedEventContractTest {

    public static final String PARITAIR_COMITE_ID = "01234567890123456789012345678901";

    @Pact(consumer = "dimona-service")
    V4Pact paritairComiteChangedEventPact(PactBuilder builder) {
        PactDslJsonBody body = new PactDslJsonBody();
        body.stringMatcher("id", "^[a-zA-Z0-9]{32}$", PARITAIR_COMITE_ID);

        Map<String, Object> metadata = new HashMap<>();
        metadata.put("Content-Type", "application/json");

        return builder.usingLegacyMessageDsl()
                .expectsToReceive("valid ParitairComiteChangedEvent from wg-sector-service")
                .withMetadata(metadata)
                .withContent(body)
                .toPact();
    }


    @Test
    @PactTestFor(pactMethod = "paritairComiteChangedEventPact")
    void test(V4Pact pact) {
        V4Interaction.AsynchronousMessage message = (V4Interaction.AsynchronousMessage) pact.getInteractions()
                .stream().filter(i -> i instanceof V4Interaction.AsynchronousMessage).findFirst().get();
        assertThat(message.getContents().getContents().valueAsString(), is("{\"id\":\"" + PARITAIR_COMITE_ID + "\"}"));
    }
}
u
Yes, that's the way to do it. I think you can also inject the messages if you don't want the whole pact class
m
Ow yes that works as well thanks for that tip.
t
Recently I was also looking for a valid example of how to make use of
V4Pact
for messages and also came up with a similar solution like @Michael Branders. What confused me about that was the use of
usingLegacyMessageDsl
though🤔 Maybe it's because of the naming, but to me this method kind of sounds like it should not be used 🤷‍♂️ Is there also any "non-legacy" way of creating V4Pacts for messages? Sorry for reviving this old thread!
u
I was hoping of creating a new DSL that better supports all the V4 options, and then people could still use the old ones. Just haven't had the time to do that yet.