集成测试给出编译错误 CS0051
Integration tests give compilation error CS0051
我正在使用 ASP.NET 6 Core 并为使用模拟 DBContext
的控制器编写基本集成测试。尝试以 Microsoft docs 为基础。但我无法构建,因为我得到
CS0051 Inconsistent accessibility: parameter type 'CustomWebApplicationFactory<Program>' is less accessible than method 'ProjectsControllerTests.ProjectsControllerTests(CustomWebApplicationFactory<Program>)' DatabaseManagerService
但他们都是 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);
}
}
});
}
}
Program
class 不是 ASP.NET 6 Core 中的 public。根据 https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60-samples?view=aspnetcore-6.0#twa,您可以通过将以下内容附加到 Program.cs 来制作 Program
public:
public partial class Program { }
还需要注意的是,上面的测试class必须定义为:
public class ProjectsControllerTests : IClassFixture<CustomWebApplicationFactory<Program>>
让 DI 工作。
我正在使用 ASP.NET 6 Core 并为使用模拟 DBContext
的控制器编写基本集成测试。尝试以 Microsoft docs 为基础。但我无法构建,因为我得到
CS0051 Inconsistent accessibility: parameter type 'CustomWebApplicationFactory<Program>' is less accessible than method 'ProjectsControllerTests.ProjectsControllerTests(CustomWebApplicationFactory<Program>)' DatabaseManagerService
但他们都是 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);
}
}
});
}
}
Program
class 不是 ASP.NET 6 Core 中的 public。根据 https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60-samples?view=aspnetcore-6.0#twa,您可以通过将以下内容附加到 Program.cs 来制作 Program
public:
public partial class Program { }
还需要注意的是,上面的测试class必须定义为:
public class ProjectsControllerTests : IClassFixture<CustomWebApplicationFactory<Program>>
让 DI 工作。