I'm using ASP.NET 6 Core and writing a basic integration test for a controller that uses a mocked DBContext
. Trying to base it on the Microsoft docs. But I can't build because I'm getting
CS0051 Inconsistent accessibility: parameter type 'CustomWebApplicationFactory<Program>' is less accessible than method 'ProjectsControllerTests.ProjectsControllerTests(CustomWebApplicationFactory<Program>)' DatabaseManagerService
But they are both public?!
ProjectControllersTests.cs
public class ProjectsControllerTests
{
private readonly CustomWebApplicationFactory<Program> _factory;
private const string s_apiBaseUri = "/api/v1";
public ProjectsControllerTests(CustomWebApplicationFactory<Program> factory)
{
// Arrange
_factory = factory;
}
[Fact]
public async Task Post_Responds201IfAuthenticatedAndRequiredFields_SuccessAsync()
{
// Arrange
HttpClient? client = _factory.CreateClient(new WebApplicationFactoryClientOptions()
{
AllowAutoRedirect = false
});
var project = new Project() { Name = "Test Project" };
var httpContent = new StringContent(JsonSerializer.Serialize(project));
// Act
var response = await client.PostAsync($"{s_apiBaseUri}/projects", httpContent);
// Assert
Assert.Equal(System.Net.HttpStatusCode.Created, response.StatusCode);
}
}
CustomWebApplicationFactory.cs
public class CustomWebApplicationFactory<TStartup>
: WebApplicationFactory<TStartup> where TStartup : class
{
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("InMemoryDbForTesting");
});
services.AddAuthentication("Test")
.AddScheme<AuthenticationSchemeOptions, MockAuthHandler>(
"Test", options => { });
var sp = services.BuildServiceProvider();
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<myDbContext>();
var logger = scopedServices
.GetRequiredService<ILogger<CustomWebApplicationFactory<Program>>>();
db.Database.EnsureCreated();
try
{
db.EndUsers.Add(new DataAccessLibrary.Models.EndUser() { ObjectIdentifier = "test-oid" });
db.SaveChanges();
}
catch (Exception ex)
{
logger.LogError(ex, "An error occurred seeding the "
"database with test messages. Error: {Message}", ex.Message);
}
}
});
}
}
CodePudding user response:
The Program
class is not public in ASP.NET 6 Core. As per https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60-samples?view=aspnetcore-6.0#twa you can make Program
public by appending the following to Program.cs:
public partial class Program { }
It should also be noted that the above test class must be defined as:
public class ProjectsControllerTests : IClassFixture<CustomWebApplicationFactory<Program>>
for DI to work.