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
The host is typically configured, built, and run by code in the Program class. The Main method: Calls a CreateHostBuilder method to create and configure a builder object. Calls Build and Run methods on the builder object.
ConfigureAppConfiguration(IHostBuilder, Action<IConfigurationBuilder>) Sets up the configuration for the remainder of the build process and application. This can be called multiple times and the results will be additive. The results will be available at Configuration for subsequent operations, as well as in Services.
NET Core 2.2 use the Web Host for web application. The Generic host got included with ASP.NET CORE 2.1 and became the de-facto standard for the future version of . NET Core. Though the Generic host got included in . NET core 2.1 it was only used for non HTTP workloads.
The Generic Host can be used with other types of . NET applications, such as Console apps. A host is an object that encapsulates an app's resources and lifetime functionality, such as: Dependency injection (DI)
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/
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With