Hi Team, I am trying to validate the generated co...
# pact-jvm
p
Hi Team, I am trying to validate the generated contracts through "context.verifyInteraction()" but I am getting "400" error code , can you please check if I am missing something here
I am not able to debug to see what end point is taking during execution from "context"
b
Why are you pulling pacts from the target/pacts folder? I highly doubt your code will find them there
p
Thanks for response @Bas Dijkstra So it should be from PactBroker directly? Reason of trying to pull from folder is , want to try option where I will not use Pact Broker and just share my contract files with Provider manually and provider run provider test at provider side.
b
Yes I get that, but the target folder is a really weird choice for a location as it will get wiped every time you run ‘mvn clean’
p
okay understood, I can move it to resources folder. Any other things which I am doing incorrect?
b
Since the response content type you’re getting is text/html I suspect you’re hitting some kind of proxy / gateway that requires authentication or something else. I’ve not really run tests against AWS hosted APIs so I can’t help in more detail here.
f
I’m not sure the suggestion to move to contract out of the target folder would make a difference here. Also, I don’t see this as incorrect since it can be used for locally debugging your contracts before publishing them to an online broker.
All my contracts have always been pulled from that folder and that has never been an issue.
Copy code
@Provider(PACT_PROVIDER)
/* Uncomment this and comment @PactBroker instead to test locally by pasting a .json file for the contract under
 the target/pacts folder */
@PactFolder("target/pacts")
// @PactBroker(host = BROKER_PACT_URL, consumers = {"MY_CONSUMER"})
@VerificationReports(value = {"markdown"}, reportDir = "target/pacts")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Sql(scripts = {"classpath:clean-up.sql", "classpath:init.sql"}, executionPhase = BEFORE_TEST_METHOD)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class ProviderIT extends BasePostgresConfig {

    @LocalServerPort
    int port;

    RequestSpecification rq;

    @BeforeAll
    void setUp() {
        Map<String, String> headers = new HashMap<>();
        rq = getRequestSpecification().baseUri("<http://localhost>:" + port)
                .contentType(ContentType.JSON)
                .headers(headers);
    }

    @TestTemplate
    @ExtendWith(PactVerificationInvocationContextProvider.class)
    void pactTestTemplate(PactVerificationContext context, HttpRequest request) {
        logCurlFromPact(context, request, "<http://localhost>:" + port);
        context.verifyInteraction();
    }

    @BeforeEach
    void before(PactVerificationContext context) {
        context.setTarget(new HttpTestTarget("localhost", port, ""));
    }

    @State("A request to retrieve a product")
    Map<String, Object> getProduct() {
        Map<String, Object> map = new HashMap<>();
        map.put("productId", "d3256c76-62d7-4481-9d1c-a0ccc4da380f");
        return map;
    }
}
The target folder is the default location for where the contracts go once they are generated.
Now, in answer to the original question: 400 normally indicates a request error, and the body returned as html probably indicates an error message is being returned by the api instead of a valid successful json.
Pact can be hard to debug sometimes, so for this I’ve created a helper code that I use, which gives me the curl for the request printed back to the terminal.
Perhaps it may be useful to you also.
Copy code
public static void logCurlFromPact(PactVerificationContext context, HttpRequest request, String baseUri) {
    String bodyParam = ((RequestResponseInteraction) context.getInteraction()).getRequest().getBody().valueAsString();
    String bodyResponse = ((RequestResponseInteraction) context.getInteraction()).getResponse().getBody().valueAsString();
    String method = ((RequestResponseInteraction) context.getInteraction()).getRequest().getMethod();

    String url = baseUri + request.getPath();

    Header[] headers = request.getHeaders();
    String headersString = "";
    for (Header s : headers) {
        headersString = headersString + "--header " + "'" + s.getName() + ": " + s.getValue() + "'" + "\\" + "\n";
    }

    String curl = """
            curl --request %s '%s' \
            %s --data-binary '%s' \
            --compressed --insecure --verbose
            """.formatted(method, url, headersString, bodyParam);


    log.debug(curl + "\n\n " + bodyResponse + "\n ---- \n\n");
}
Log can be replaced by System.out if not using a logger library.
Then you should be able to see your request as per the below screenshot, which may help you compare why it’s different from a valid request.
b
Thanks @Francislainy Campos!
👍 1
p
Thanks @Francislainy Campos and @Bas Dijkstra I will check above example and see if I am missing something
👍 1