我正在为 .NET Core 3.1 Web API
进行集成测试。我按照这篇文章《ASP.NET Core Web API的无痛集成测试》进行操作。这是我的CustomWebApplicationFactory
:
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<TestDbContext>));
if (descriptor != null)
{
services.Remove(descriptor);
}
services.AddDbContext<TestDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryTestDb");
});
var sp = services.BuildServiceProvider();
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<TestDbContext>();
var logger = scopedServices.GetRequiredService<ILogger<CustomWebApplicationFactory<TStartup>>>();
db.Database.EnsureCreated();
try
{
Console.WriteLine("Seeding...");
var players = Utilities.GetTestPlayers(); // Returns 3 test players
db.Players.RemoveRange(db.Players); // Clear the table
db.Players.AddRange(players); // Add 3 test players
db.SaveChanges();
Console.WriteLine($"Players seeded: { db.Players.Count() }");
}
catch (Exception ex)
{
logger.LogError(ex, "An error occurred seeding the " + "database with test messages. Error: {Message}", ex.Message);
}
}
});
}
}
这是我的测试: 对于每个控制器(Controller)
,我都会创建一个单独的测试类。在测试类的构造函数中,我会创建一个客户端(Client)
。就像对于TestController
(API中共有4个控制器):
public class BaseControllerTest : IClassFixture<CustomWebApplicationFactory<Startup>>
{
protected HttpClient Client { get; }
public BaseControllerTest(CustomWebApplicationFactory<Startup> factory)
{
Client = factory.CreateClient();
}
}
public class TestControllerShould : BaseControllerTest
{
public TestControllerShould(CustomWebApplicationFactory<Startup> factory)
: base(factory)
{
Console.WriteLine("TestControllerShould");
}
[Fact]
public async Task GetHelloWorld()
{
var request = new HttpRequestMessage(new HttpMethod("GET"), "/test/");
var response = await Client.SendAsync(request);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
Assert.Equal("Hello World!", content);
Assert.False(response.Headers.Contains("Server"), "Should not contain server header");
}
}
我的问题是:
正如您在CustomWebApplicationFactory
中看到的,我正在进行日志记录,同时正在进行种子处理,这是我看到的日志:
Seeding...
Seeding...
Seeding...
Seeding...
Players seeded: 12
Players seeded: 12
Players seeded: 12
Players seeded: 12
我总共有4个控制器,但只播种了3个玩家。为什么我看到的是12个?我不明白。看起来在任何
db.SaveChanges();
之前,每个控制器测试类都会调用db.Players.AddRange(players);
4次。然后连续4次调用了db.SaveChanges();
。为什么?我的问题是:为什么会这样?如何正确地在集成测试中种植测试数据?
(如果不是通过答案,请引用一篇好的文章将非常感谢)
谢谢