我在整合测试中the毁了mayysoft docs网站上的以下代码,并对其进行了一些改动以满足我的需求:
public class CustomWebApplicationFactory<TStartup>
: WebApplicationFactory<TStartup> where TStartup : class
{
private readonly SeedDataClass _seed;
public CustomWebApplicationFactory(SeedDataClass seed)
{
_seed = seed;
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
base.ConfigureWebHost(builder);
builder.UseEnvironment("Development");
builder.ConfigureServices(services =>
{
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
services.AddSingleton(_seed);
services.AddDbContextPool<GatewayContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
options.UseInternalServiceProvider(serviceProvider);
options.EnableSensitiveDataLogging();
});
var sp = services.BuildServiceProvider();
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<GatewayContext>();
var logger = scopedServices
.GetRequiredService<ILogger<CustomWebApplicationFactory<TStartup>>>();
var seed = scopedServices.GetRequiredService<SeedDataClass>();
db.Database.EnsureCreated();
try
{
seed.InitializeDbForTests(db);
}
catch (Exception ex)
{
logger.LogError(ex, $"An error occurred seeding the database with test messages. Error: {ex.Message}");
}
}
});
}
}
要像在以下测试中一样使用:
_client = new CustomWebApplicationFactory<Startup>(new SeedDataClass()).CreateClient();
这一切都可行,但是我希望将泛型添加到自定义Web应用程序工厂类中,并将此代码移到正在处理的nuget包中,以进行内部测试。
类似这样的东西:
public class CustomWebApplicationFactory<TStartup, TContext>
: WebApplicationFactory<TStartup>
where TStartup : class
where TContext : DbContext
我一直坚持如何将SeedDataClass
类实例提供/注入到新的通用自定义Web应用程序工厂中。
答案 0 :(得分:1)
如果您只是想将类似的构造函数改编为CustomWebApplicationFactory<TStartup>
类的先前实现
_client = new CustomWebApplicationFactory<Startup>(new SeedDataClass()).CreateClient();
然后您的新构造函数将如下所示:
public class CustomWebApplicationFactory<TStartup, TContext> : WebApplicationFactory<TStartup>
where TStartup : class
where TContext : DbContext
{
private readonly SeedDataClass _seed;
public CustomWebApplicationFactory(SeedDataClass seed)
{
if (seed == null) throw new ArgumentNullException(nameof(seed));
_seed = seed;
}
}
然后像这样更新对构造函数的调用
new CustomWebApplicationFactory<Startup, YourDbContext>(new SeedDataClass()).CreateClient();
答案 1 :(得分:0)
这就是我要去的地方
修正工厂:
public class GenericWebApplicationFactory<TStartup, TContext, TSeed>
: WebApplicationFactory<TStartup>
where TStartup : class
where TContext : DbContext
where TSeed : class, ISeedDataClass
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
base.ConfigureWebHost(builder);
builder.UseEnvironment("Development");
builder.ConfigureServices(services =>
{
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
services.AddSingleton<ISeedDataClass,TSeed >();
services.AddDbContextPool<TContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
options.UseInternalServiceProvider(serviceProvider);
options.EnableSensitiveDataLogging();
});
var sp = services.BuildServiceProvider();
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<TContext>();
var logger = scopedServices.GetRequiredService<ILogger<GenericWebApplicationFactory<TStartup, TContext, TSeed>>>();
var seeder = scopedServices.GetRequiredService<ISeedDataClass>();
db.Database.EnsureCreated();
try
{
seeder.InitializeDbForTests();
}
catch (Exception ex)
{
logger.LogError(ex, $"An error occurred seeding the database with test messages. Error: {ex.Message}");
}
}
});
}
}
推荐用法:
_client = new GenericWebApplicationFactory<Startup, GatewayContext, SeedDataClass>().CreateClient();
带有示例种子类:
public interface ISeedDataClass
{
void InitializeDbForTests();
}
public class SeedDataClass : ISeedDataClass
{
private readonly GatewayContext _db;
public SeedDataClass(GatewayContext db)
{
_db = db;
}
public void InitializeDbForTests()
{
_db.Users.AddRange(
// add some users here
);
_db.SaveChanges(true);
}
}
现在,我可以在内存数据库中播种种子,但是我认为适合每个应用项目,并且我的GenericWebApplicationFactory
现在可以放入helper lib / nuget包中,可以在其他项目中重新使用。