Skip to content

Provider state parameters are serialised as numbers, causes errors in provider state middleware when using System.Text.Json #449

@DavidJFowler

Description

@DavidJFowler

If the value of a provider state parameter is a number string, it is serialised in the pact file as a number. This is an issue if the provider state middleware in the provider tests uses System.Text.Json to deserialise a ProviderState value as System.Text.Json does not deserialise non-string values into string properties. https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/migrate-from-newtonsoft?pivots=dotnet-6-0#non-string-values-for-string-properties.

For example:

using System.Net;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using PactNet;

var config = new PactConfig
{
    PactDir = Path.Join("..", "..", "..", "pacts"),
    DefaultJsonSettings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),

    }
};

var pact = Pact.V3("consumer", "provider", config).WithHttpInteractions();

pact.UponReceiving("A valid request")
    .Given("state with parameter", new Dictionary<string, string>() {["id"] = "10", ["name"] = "Fred"})
    .WithRequest(HttpMethod.Get, "/api/endpoint")
    .WillRespond()
    .WithStatus(HttpStatusCode.OK);

await pact.VerifyAsync(async ctx =>
{
    using var apiClient = new ApiClient(ctx.MockServerUri);

    await apiClient.TestRequestAsync();
});

public class ApiClient: IDisposable
{
    private readonly HttpClient _httpClient;

    public ApiClient(Uri baseUri)
    {
        _httpClient = new HttpClient { BaseAddress = baseUri };
    }

    public async Task TestRequestAsync()
    {
        await _httpClient.GetAsync("api/endpoint");
    }

    public void Dispose()
    {
        _httpClient.Dispose();
    }
}

generates this pact. Note that parameter "id" is serialised as 10 not "10".

{
  "consumer": {
    "name": "consumer"
  },
  "interactions": [
    {
      "description": "A valid request",
      "providerStates": [
        {
          "name": "state with parameter",
          "params": {
            "id": 10,
            "name": "Fred"
          }
        }
      ],
      "request": {
        "method": "GET",
        "path": "/api/endpoint"
      },
      "response": {
        "status": 200
      }
    }
  ],
  "metadata": {
    "pactRust": {
      "ffi": "0.4.0",
      "models": "1.0.4"
    },
    "pactSpecification": {
      "version": "3.0.0"
    }
  },
  "provider": {
    "name": "provider"
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIndicates an unexpected problem or unintended behaviorupstreamIndicates that an issue relates to an upstream problem (such as in pact-reference)wontfixIndicates that work won't continue on an issue, pull request, or discussion

    Type

    No type

    Projects

    Status

    Closed

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions