8000 Messaging pacts - WithContentAsync - factory is invoked before provider state has been set · Issue #459 · pact-foundation/pact-net · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Messaging pacts - WithContentAsync - factory is invoked before provider state has been set #459
Open
@DavidJFowler

Description

@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:

<ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

add the following package refs:

<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:

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 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

Assert.That(isProviderStatesCalled, Is.True);

fails because the POST to provider-states has not been made.

Changing to WithContent works:

/* ... */

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();

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageThis issue is yet to be triaged by a maintainer

    Type

    No type

    Projects

    Status

    New Issue

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0