18

I'm trying to setup my application in tests and use in Startup's Configure method context.Database.EnsureCreated() and expecting Sqlite file appear in Test's bin folder

Here's my code:

using Microsoft.AspNetCore.Mvc.Testing;
using System.Threading.Tasks;
using Xunit;

namespace MyApp.Tests
{
    public class UnitTest1 : IClassFixture<CustomWebApplicationFactory<FakeStartup>>
    {
        private readonly CustomWebApplicationFactory<FakeStartup> _factory;

        public UnitTest1(CustomWebApplicationFactory<FakeStartup> factory)
        {
            _factory = factory;
        }

        [Fact]
        public async Task Test1()
        {
            // Arrange
            var client = _factory.CreateClient();

            // Act
            var response = await client.GetAsync("https://localhost:5001/");

            // Assert
            response.EnsureSuccessStatusCode(); // Status Code 200-299
            Assert.Equal("text/html; charset=utf-8", response.Content.Headers.ContentType.ToString());
        }
    }
}

Which is using WebAppFactory:

using MyApp.Tests;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;

public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseStartup<FakeStartup>();
    }
}

Where FakeStartup is:

using MyApp.Database;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace MyApp.Tests
{
    public class FakeStartup
    {
        public FakeStartup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {            
            services.AddControllers();

            services.AddDbContext<Context>(x => x.UseSqlite($"filename={Guid.NewGuid():N}.db"));

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Test API", Version = "v1" });
            });
        }
    }

    public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, Context context)
    {
        context.Database.EnsureDeleted();
        context.Database.EnsureCreated();

        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "Test API v1");
            c.RoutePrefix = string.Empty;
        });

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

        app.UseAuthentication();

        app.UseCors(x =>
        {
            x.AllowAnyOrigin();
            x.AllowAnyMethod();
            x.AllowAnyHeader();
        });

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

Here's problem

  Message: 
    System.InvalidOperationException : No method 'public static IHostBuilder CreateHostBuilder(string[] args)' or 'public static IWebHostBuilder CreateWebHostBuilder(string[] args)' found on 'AutoGeneratedProgram'. Alternatively, WebApplicationFactory`1 can be extended and 'CreateHostBuilder' or 'CreateWebHostBuilder' can be overridden to provide your own instance.
  Stack Trace: 
    WebApplicationFactory`1.CreateWebHostBuilder()
    WebApplicationFactory`1.EnsureServer()
    WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
    WebApplicationFactory`1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers)
    WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
    WebApplicationFactory`1.CreateClient()
    UnitTest1.Test1() line 20
    --- End of stack trace from previous location where exception was thrown

What may be causing this? thanks in advance

3 Answers 3

33

Updated with comment from CoreyP:

If you are getting this error and you're on .NET 6.0, you might need to update the Microsoft.AspNetCore.Mvc.Testing package, see this question: Integration test for ASP.NET Core 6 web API throws System.InvalidOperationException

Solution:

Create CustomWebApplicationFactory this way

public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
    protected override IHostBuilder CreateHostBuilder()
    {
        var builder = Host.CreateDefaultBuilder()
                          .ConfigureWebHostDefaults(x =>
                          {
                              x.UseStartup<FakeStartup>().UseTestServer();
                          });
        return builder;
    }
}

Found here:

https://thecodebuzz.com/no-method-public-static-ihostbuilder-createhostbuilder/

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

6 Comments

UseTestServer() is not supported in dotnet core 3.1 (to the best of my understanding). Do you have a solution that works for .net core 3.1?
@PMO1948 I'm using it on .NET 5, so I'm surprised it's not a part of .NET Core 3.1.
hey, that was actually my mistake - I was trying to use the 2.2 version with 3.1, and that's why it didnt't work
If you're here for dotnet 6.0, checkout this answer
Hi, I have a problem with this solution. I have my sln file in a folder, and projects in the "src" subfolder. When creating WebApplicationFactory it tries to find the My.Test.Folder in the same directory of the SLN file. How can I solve, without creating the empty folder?
|
4

I was getting this error because I had not followed the MS prerequisites closely enough. In my case I had not updated the Project SDK in the test csproj file. It needs to be <Project Sdk="Microsoft.NET.Sdk.Web"> (note the '.Web' on the end).

Comments

0

I was this error because I was using and old version of Microsoft.AspNetCore.Mvc.Testing package

After upgrading version to the latest version the error was resolved.

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.