Integration test for ASP.NET Core 6 web API throws System.InvalidOperationException
Asked Answered
P

2

7

I'm trying to understand how to do integration tests on ASP.NET Core 6 web API controllers. I've tried following all the guides, SO posts and recommendations I could find but for some reason I keep hitting errors that aren't mentioned in the guides.

EventControllerTests.cs

namespace UnitTests.ProjectToBeTested.Controllers
{
    public class EventControllerTests
    {
        [Fact]
        public async Task EventController_Post_RespondsOkIfRequestContainsCorrectFeilds_SuccessAsync()
        {

            // Arrange
            var application = new WebApplicationFactory<Program>();

            var client = application.CreateClient();
            ...

ProjectToBeTested.csproj

...
    <ItemGroup>
        <InternalsVisibleTo Include="IntegrationTests" />
    </ItemGroup>
...

This throws the following when running the test:

Message:  System.InvalidOperationException : No method 'public static IHostBuilder CreateHostBuilder(string[] args)' or 'public static IWebHostBuilder CreateWebHostBuilder(string[] args)' found on 'Program'. Alternatively, WebApplicationFactory`1 can be extended and 'CreateHostBuilder' or 'CreateWebHostBuilder' can be overridden to provide your own instance.

Stack Trace:  WebApplicationFactory1.CreateWebHostBuilder() WebApplicationFactory1.EnsureServer() WebApplicationFactory1.CreateDefaultClient(DelegatingHandler[] handlers) WebApplicationFactory1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers) WebApplicationFactory1.CreateClient(WebApplicationFactoryClientOptions options) WebApplicationFactory1.CreateClient() EventControllerTests.EventController_Post_RespondsOkIfRequestContainsCorrectFeilds_SuccessAsync() line 17 --- End of stack trace from previous location ---

This SO post shows up as a possible solution but is using pre-6 using a Startup class. What would the .NET 6 solution be?

If I instead follow the "Basic tests with the default WebApplicationFactory"-guide I can't even build the solution because of the test class constructor throwing

Error CS0051 Inconsistent accessibility: parameter type 'WebApplicationFactory' is less accessible than method 'EventControllerTests.EventControllerTests(WebApplicationFactory)' IntegrationTests C:\...\EventControllerTests.cs

Paid answered 15/10, 2021 at 14:21 Comment(8)
You can use startup.cs like this https://mcmap.net/q/193385/-startup-cs-in-a-self-hosted-net-core-console-applicationCeladon
@viveknuna there's no Startup.cs in an ASP.NET 6 Minimal APIUrga
Which .NET 6 version are you using? RC1? RC2? Make sure you upgrade to the latest version. What does your Program.cs look like?Urga
@PanagiotisKanavos AFAIK it should be there, but minimal API is just a style of doing, no enforcement, right? let me read the documentationCeladon
Wrong. There's no such class. That code is now in Program.csUrga
@PanagiotisKanavos Sorry for leaving that out. I've tried both RC1 and RC2.Paid
@r.r I can't reproduce any problem. I created a new webapi project from the command line with dotnet new webapi and a unit test with dotnet new xunit. I added Microsoft.AspNetCore.Mvc.Testing to the test project and was able to create an application with the code you posted. I did encounter problems when I created the projects through Jetbrains RiderUrga
Don't put Solved in the title or include the answer in the question. You've posted an answer and accepted it, that's good enough.Unific
P
11

Solution:

This was due to the Microsoft.AspNetCore.Mvc.Testing package for the test project using the wrong version (it was using version 5.*). Make sure that you use a version suitable for .NET 6. As of now there is a 6.0.0-rc.2.21480.10 version that works for me.

Paid answered 18/10, 2021 at 14:35 Comment(1)
That was it! Didn't even think about the packages I had to upgrade after migrating to dotnet 6.0Skysweeper
U
3

I can't reproduce this. I created two new projects from the command line on .NET 6 RC1 with

dotnet new webapi -o webapi1
dotnet new xunit -o test1
dotnet new sln

Web API project

The only change I made to the Web API project was to add this to the project file:

  <ItemGroup>
    <InternalsVisibleTo Include="test1" />
  </ItemGroup>

Program.cs remained unchanged:

using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new() { Title = "webapi2", Version = "v1" });
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "webapi2 v1"));
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Test project

In the test project I added a reference to webapi1 and the Microsoft.AspNetCore.Mvc.Testing package.

I changed Unit1.cs to

using Microsoft.AspNetCore.Mvc.Testing;
using Xunit;
using webapi2;

namespace test1;

public class UnitTest1
{
    [Fact]
    public void Test1()
    {
        using var app = new WebApplicationFactory<Program>();
        using var client=app.CreateClient();
    }
}

The projects compiled and the test run succesfully.

Urga answered 15/10, 2021 at 16:1 Comment(2)
Very weird. I created a new solution and following your steps but I'm not able to run the test, still get the "No method 'public static..." error, even in the new solution. This was with RC2 and VS 2022 Preview 5.0 thought.Paid
Gotcha! Adding the InternalsVisibleTo project config entry solved the problem!Herodotus

© 2022 - 2024 — McMap. All rights reserved.