Skip to content

axle-h/xunit-fixture-mvc

Repository files navigation

CircleCI NuGet

xunit-fixture-mvc

MVC functional tests with a fixture pattern.

Example

public class BreakfastItemTests {
    private readonly ITestOutputHelper _output;

    public BreakfastItemTests(ITestOutputHelper output)
    {
        _output = output;
    }

    [Fact]
    public Task When_creating_breakfast_item() =>
        new MvcFunctionalTestFixture<Startup>(_output)
            .WhenCreating("BreakfastItem", out CreateOrUpdateBreakfastItemRequest request)
            .ShouldReturnSuccessfulStatus()
            .ShouldReturnEquivalentJson<BreakfastItem, CreateOrUpdateBreakfastItemRequest>(request)
            .ShouldReturnJson<BreakfastItem>(r => r.Id.Should().NotBeNullOrEmpty())
            .RunAsync();
}

This already reads pretty well but let's break it down:

new MvcFunctionalTestFixture<Startup>(_output)

Configures the test server to use the specified startup class and to send all logs to the xunit test context.

.WhenCreating("BreakfastItem", out CreateOrUpdateBreakfastItemRequest request)

Configures the fixture to send a POST /BreakfastItem request to the test server once it's up and running. We're also asking the fixture to use AutoFixture to create a new instance of the request class and return it to us in an out parameter.

.ShouldReturnSuccessfulStatus()

Adds an assertion to the fixture that the response has a successful (2xx) code.

.ShouldReturnEquivalentJson<BreakfastItem, CreateOrUpdateBreakfastItemRequest>(request)
.ShouldReturnJson<BreakfastItem>(r => r.Id.Should().NotBeNullOrEmpty())

Both of these add an assertion to the fixture that the response body is JSON that can be deserialized to an instance of BreakfastItem. The first line adds an assertion that the deserialized response is equivalent to the request object according to FluentAssertions amazing equivalence feature. The second line adds an assertion that the Id property of the response has been set to something other than null or the empty string.

.RunAsync();

This actually runs the fixture. The configuration will mean that it will:

  1. Create a new test server to host the API that we're testing.
  2. Send a POST /BreakfastItem request to the API with a JSON request body serialized from the generated CreateOrUpdateBreakfastItemRequest.
  3. Assert that the response has a successful (2xx) code.
  4. Attempt to deserialize the response body as a BreakfastItem and run assertions on the deserialized object.
  5. If no exceptions are thrown, do nothing and let the test pass. Otherwise:
    • If one exception is thrown => re-throw the exception.
    • If multiple exceptions are thrown => throw an aggregate exception containing all thrown exceptions.

About

Simple fixture based integration test pattern for MVC

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages