<#459 Messaging pacts - WithContentAsync - factory...
# pact-net
g
#459 Messaging pacts - WithContentAsync - factory is invoked before provider state has been set Issue created by DavidJFowler When verifying a messaging pact scenario using WithContentAsync, the factory Func is invoked before a POST to /provider-states has completed. To reproduce, create a dotnet 7 console app. Add a FrameworkReference to Microsoft.AspNetCore.App in the .csproj file:
Copy code
<ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
add the following package refs:
Copy code
<ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
    <PackageReference Include="NUnit" Version="3.13.3" />
    <PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
    <PackageReference Include="PactNet" Version="4.5.0" />
  </ItemGroup>
Edit program.cs:
Copy code
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using NUnit.Framework;
using PactNet;
using PactNet.Matchers;
using PactNet.Verifier;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using <http://System.Net|System.Net>;
using Microsoft.AspNetCore.Http;

// create pact
var pactDir = Path.Join("..", "..", "..", "pacts");
var v3 = Pact.V3("Message Consumer", "Message Producer", new PactConfig
{
    PactDir = pactDir,
    DefaultJsonSettings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver()
    }
});

var messagePact = v3.WithMessageInteractions();

messagePact.ExpectsToReceive("some events")
    .Given("events exist")
    .WithJsonContent(Match.MinType(new { MessageText = "Hello World"}, 1))
    .Verify<ICollection<MyMessage>>(events => Assert.That(events, Is.Not.Empty));

// verify pact

// configure provider states handler
var isProviderStatesCalled = false;
const string pactProviderServiceUri = "<http://127.0.0.1:9001>";
var builder = WebApplication.CreateBuilder(new WebApplicationOptions());
builder.WebHost.UseUrls(pactProviderServiceUri);
await using var app = builder.Build();
app.MapPost("/provider-states", async context =>
{
    isProviderStatesCalled = true;
    context.Response.StatusCode = (int) HttpStatusCode.OK;
    await context.Response.WriteAsync(string.Empty);
});

await app.StartAsync();

var verifier = new PactVerifier(new PactVerifierConfig
{
    LogLevel = PactLogLevel.Debug
});

var defaultSettings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver(),
    DefaultValueHandling = DefaultValueHandling.Ignore,
    NullValueHandling = NullValueHandling.Ignore,
    Formatting = Formatting.Indented
};

verifier.MessagingProvider("Message Producer", defaultSettings)
    .WithProviderMessages(scenarios =>
    {
        scenarios.Add("some events", scenarioBuilder =>
        {
            return scenarioBuilder.WithContentAsync(async () =>
            {
                var events = new List<MyMessage>
                {
                    new MyMessage
                    {
                        MessageText = "Hello World"
                    }
                };

                Assert.That(isProviderStatesCalled, Is.True);

                await Task.CompletedTask;

                return events;
            });
        });
    }).WithFileSource(new FileInfo(Path.Join(pactDir, "Message Consumer-Message Producer.json")))
    .WithProviderStateUrl(new Uri(new Uri(pactProviderServiceUri), "/provider-states"))
    .Verify();

await app.StopAsync();

Console.WriteLine($"isProviderStatesCalled {isProviderStatesCalled}");

public class MyMessage
{
    public string MessageText { get; set; }
}
On running the app, the assertion
Copy code
Assert.That(isProviderStatesCalled, Is.True);
fails because the POST to provider-states has not been made. Changing to WithContent works:
Copy code
/* ... */

verifier.MessagingProvider("Message Producer", defaultSettings)
    .WithProviderMessages(scenarios =>
    {
        scenarios.Add("some events", scenarioBuilder =>
        {
            scenarioBuilder.WithContent(() =>
            {
                var events = new List<MyMessage>
                {
                    new MyMessage
                    {
                        MessageText = "Hello World"
                    }
                };

                Assert.That(isProviderStatesCalled, Is.True);

                return events;
            });
        });
    }).WithFileSource(new FileInfo(Path.Join(pactDir, "Message Consumer-Message Producer.json")))
    .WithProviderStateUrl(new Uri(new Uri(pactProviderServiceUri), "/provider-states"))
    .Verify();
pact-foundation/pact-net