9

I followed the documentation of microsoft for Integration testing: https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-6.0#introduction-to-integration-tests

In .net core 6, startup.cs has been removed, the integration testing I used before doesn't work anymore as is. I need to do an update.

In my API csproj, I added:

<ItemGroup>
        <InternalsVisibleTo Include="Integration.Tests" />
</ItemGroup>

and here is the Integration.Tests csproj:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <IsPackable>false</IsPackable>
        <IsTestProject>true</IsTestProject>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
        <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.0" />
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
        <PackageReference Include="xunit" Version="2.4.1" />
        <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
            <PrivateAssets>all</PrivateAssets>
        </PackageReference>
        <PackageReference Include="coverlet.collector" Version="3.1.0">
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
            <PrivateAssets>all</PrivateAssets>
        </PackageReference>
    </ItemGroup>

    

</Project>

I created a TestWebAppFactory.cs like:

public class TestWebAppFactory<TEntryPoint> : WebApplicationFactory<Program> where TEntryPoint : Program
{
    public ITestOutputHelper Output { get; set; }
    public List<string> Logs { get; private set; } = new List<string>();

    public TestWebAppFactory([NotNull] ITestOutputHelper output)
    {
        Output = output;
    }

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder
            .ConfigureServices(services =>
            {
                var descriptor = services.SingleOrDefault(
                    d => d.ServiceType ==
                        typeof(DbContextOptions<MyDbContext>));

                if (descriptor != null)
                {
                    services.Remove(descriptor);
                }

                services.AddDbContext<MyDbContext>(options =>
                {
                    options.UseInMemoryDatabase("My.Sample");
                });
            })
            .Configure(app =>  {
                var serviceProvider = app.ApplicationServices;
                using var scope = serviceProvider.CreateScope();
                var itemManager = serviceProvider.GetRequiredService<IItemManager>();
                TestDbInitializer.Seed(scope.ServiceProvider, Output);
            });

    }
}

And my Item_Tests.cs:

public class Items_Tests : IClassFixture<Program>
    {
        private readonly HttpClient _client;
        private readonly TestServer _server;
        private readonly IWebHost _host;

        public Items_Tests(ITestOutputHelper output)
        {
            var factory = new TestWebAppFactory<Program>(output);
            _client = factory
                .CreateClient();
        } 

        [Fact]
        public async Task Index_WhenCalled_ReturnsApplicationForm()
        {
            var response = await _client.GetAsync(Constants.Api.V1.Items.Url);

            response.EnsureSuccessStatusCode();

            var responseString = await response.Content.ReadAsStringAsync();

            Assert.Contains("Mark", responseString);
            Assert.Contains("Evelin", responseString);
        }

    }

Note: I would like to be able to send the ITestOuputHelper to TestWebAppFactory to write few information useful in the output that I don't share here to reduce the amount of code.

Note2: When I launch the API, every thing works correctly, I'm to see my controller in Swagger and call the get with a code 200 returnsw.

So each time the test fails here:

            var response = await _client.GetAsync(Constants.Api.V1.Items.Url);

            response.EnsureSuccessStatusCode();

The response always get a 404 error.

What should I do to make it works correctly?

Thanks

4 Answers 4

6

So finally I found why I get a 404, when I delete the .Configure section in TestWebAppFactory I'm able to connect to the API.

So now I need to found how to seed data during my test :)

Sign up to request clarification or add additional context in comments.

2 Comments

Did you find out more? I'm getting a 404 on a minimal project. Don't even ConfigureWebHost. Just a controller endpoint returning 200
Check what I have done there: github.com/ranouf/net60withnswag/tree/main/tests/… maybe it will help you, let me know
5

I had exacly the same problem. In my case, I didn't have any parameters in CreateBuilder() method when creating a builder. The solution for me was to add args parameter to CreateBuilder like below.

var builder = WebApplication.CreateBuilder(args);

Comments

1

The reason for me was to get rid of ApplicationName from WebApplicationOptions that you can pass as parameter to one of the WebApplication.CreateBuilder overloads

Comments

1

Please note that the testproject needs to be a web SDK project: <Project Sdk="Microsoft.NET.Sdk.Web"> in your .csproj.

From https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-6.0 See

With ASP.NET Core 8 (not tested 6), I get always a 404 when the integration test project is a <Project Sdk="Microsoft.NET.Sdk">

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.