sb_w
sb_w

Reputation: 11

PactNet Provider test fails because of 404 when running the test

I have a consumer that has successfully created a pact file:

{
  "consumer": {
    "name": "CakeService"
  },
  "provider": {
    "name": "CoolPersonService"
  },
  "interactions": [
    {
      "description": "A GET request to get a person who is cool",
      "providerState": "There is a person who has IsCool set to 'true'6",
      "request": {
        "method": "get",
        "path": "/CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a",
        "headers": {
          "X-Requested-With": "XMLHttpRequest",
          "CallerName": "Pact_Test@Local"
        }
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "application/json; charset=utf-8"
        },
        "body": {
          "FirstName": "Some",
          "LastName": "Name",
          "IsCool": true
        }
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "2.0.0"
    }
  }
}

The problem is the test for the provider. It gets a 404 for

/CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a

but if I send a GET to that route using an HTTP client, I get a 200 response and the expected data is returned.

Here's the output from the test run:

Test Name:  EnsureSomethingApiHonoursPactwithConsumer
Test Outcome:   Failed
Result Message: 
Test method PactTests.PactTests.EnsureSomethingApiHonoursPactwithConsumer threw exception: 
PactNet.PactFailureException: Pact verification failed. See output for details. 
If the output is empty please provide a custom config.Outputters (IOutput) for your test framework, as we couldn't write to the console.
Result StandardOutput:  
[2018-07-13 10:59:05] INFO  WEBrick 1.3.1
[2018-07-13 10:59:05] INFO  ruby 2.2.2 (2015-04-13) [i386-mingw32]
..........++++++
..........++++++
[2018-07-13 10:59:07] INFO  
[2018-07-13 10:59:07] INFO  WEBrick::HTTPServer#start: pid=109760 port=9222
[2018-07-13 10:59:07] ERROR Errno::ECONNRESET: An existing connection was forcibly closed by the remote host.
    C:/redacted/PactTests/bin/Debug/pact-win32/lib/ruby/lib/ruby/2.2.0/openssl/buffering.rb:61:in `sysread'
    C:/redacted/PactTests/bin/Debug/pact-win32/lib/ruby/lib/ruby/2.2.0/openssl/buffering.rb:61:in `fill_rbuff'
    C:/redacted/PactTests/bin/Debug/pact-win32/lib/ruby/lib/ruby/2.2.0/openssl/buffering.rb:301:in `eof?'
    C:/redacted/PactTests/bin/Debug/pact-win32/lib/vendor/ruby/2.2.0/gems/webrick-1.3.1/lib/webrick/httpserver.rb:80:in `run'
    C:/redacted/PactTests/bin/Debug/pact-win32/lib/vendor/ruby/2.2.0/gems/webrick-1.3.1/lib/webrick/server.rb:191:in `block in start_thread'
INFO: Reading pact at C:/redacted/PactTests/Pacts/cakeservice-coolpersonservice.json

Verifying a pact between CakeService and CoolPersonService
  Given There is a person who has IsCool set to 'true'6
    A GET request to get a person who is cool
      with GET /CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a
        returns a response which
DEBUG: Setting up provider state 'There is a person who has IsCool set to 'true'6' for consumer 'CakeService' using provider state server at https://localhost/CoolPersonService/provider-states
I, [2018-07-13T10:59:11.805597 #102868]  INFO -- request: POST https://localhost/CoolPersonService/provider-states
D, [2018-07-13T10:59:11.805597 #102868] DEBUG -- request: User-Agent: "Faraday v0.15.0"
Content-Type: "application/json"
I, [2018-07-13T10:59:23.352124 #102868]  INFO -- response: Status 200
D, [2018-07-13T10:59:23.352625 #102868] DEBUG -- response: content-type: "application/json; charset=utf-8"
server: "redacted"
x-powered-by: "redacted"
date: "Fri, 13 Jul 2018 08:59:23 GMT"
connection: "close"
content-length: "84"
          has status code 200 (FAILED - 1)
          has a matching body (FAILED - 2)
          includes headers
            "Content-Type" which equals "application/json; charset=utf-8" (FAILED - 3)

Failures:

  1) Verifying a pact between CakeService and CoolPersonService Given There is a person who has IsCool set to 'true'6 A GET request to get a person who is cool with GET /CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a returns a response which has status code 200
     Failure/Error: expect(response_status).to eql expected_response_status

       expected: 200
            got: 404

       (compared using eql?)

  2) Verifying a pact between CakeService and CoolPersonService Given There 

is a person who has IsCool set to 'true'6 A GET request to get a person who is cool with GET /CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a returns a response which has a matching body

>Failure/Error: expect(response_body).to match_term expected_response_body, diff_options, example
         Encoding::UndefinedConversionError:
           "\xC3" from ASCII-8BIT to UTF-8
      3) Verifying a pact between CakeService and CoolPersonService Given There is a person who has IsCool set to 'true'6 A GET request to get a person who is cool with GET /CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a returns a response which includes headers "Content-Type" which equals "application/json; charset=utf-8"
         Failure/Error: expect(header_value).to match_header(name, expected_header_value)
           Expected header "Content-Type" to equal "application/json; charset=utf-8", but was "text/html; charset=utf-8"
    1 interaction, 1 failure
    Failed interactions:
    To re-run just this failing interaction, change the verify method to '.Verify(description: "A GET request to get a person who is cool", providerState: "There is a person who has IsCool set to 'true'6")'. Please do not check in this change! # A GET request to get a person who is cool given There is a person who has IsCool set to 'true'6

Here's the test method for the provider:

[TestMethod]
[TestCategory("Pact")]
public void EnsureSomethingApiHonoursPactwithConsumer()
{
    const string serviceUri = "https://localhost/CoolPersonService";

    var config = new PactVerifierConfig
    {
        Verbose = true
    };

    IPactVerifier pactVerifier = new PactVerifier(config);
    pactVerifier
        //.ProviderState($"{serviceUri}/provider-states")
        .ProviderState($"{serviceUri}/provider-states")
        .ServiceProvider("CoolPersonService", serviceUri)
        .HonoursPactWith("CakeService")
        .PactUri(@"C:\repos\Pact\API_CoolPersonService\PactTests\Pacts\cakeservice-coolpersonservice.json")
        .Verify();
}

Upvotes: 1

Views: 3075

Answers (2)

Alec Gerona
Alec Gerona

Reputation: 2897

For those still stumped by the issue, the "\xC3" from ASCII-8BIT to UTF-8 error also happens because the response by your provider couldn't be encoded e.g. your provider returns a 500 with a text/html response.

Upvotes: 0

Beth Skurrie
Beth Skurrie

Reputation: 1318

If you do a GET to a resource, and you get a 404, to me it sounds like the expected data is not present on the server - and that implies that the provider state has not been set up correctly.

Please read about provider states here https://docs.pact.io/getting-started/provider-states and here https://docs.pact.io/implementation-guides/ruby/provider-states#non-ruby-applications

If you do a POST to the same route and receive the response you expected from a GET, it may be that you have just created a new resource, and it is returning the body of the newly created resource.

I see that you are also having some encoding issues (Encoding::UndefinedConversionError: "\xC3" from ASCII-8BIT to UTF-8) I believe this has been fixed in the latest version of the underlying library (called the "pact standalone") so please ensure you have the latest version of pact-net. If you already do have the latest version of pact-net, then please raise an issue for the standalone to be upgraded.

Upvotes: 1

Related Questions