我正在尝试使用Entity Framework Core UseInMemoryDatabase编写测试,因此我的设置如下:
[SetUp]
public void Setup()
{
this.ContextOptions = new DbContextOptionsBuilder<GeneralContext>()
.UseInMemoryDatabase(databaseName: "DiagAc2Tests")
.Options;
}
我不知道是否需要它,但是上下文看起来像:
public class GeneralContext : DbContext
{
public DbSet<Entities.Application> Applications { get; set; }
public GeneralContext() { }
public GeneralContext(DbContextOptions<GeneralContext> options) : base(options) { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var config = new DatabaseConfiguration();
optionsBuilder.UseNpgsql(config.GetConnectionString());
}
}
我在整个应用程序中都使用了此上下文,并且可以正常工作,因此我的测试如下:
public async Task CreateApplicationByService()
{
Mock<DTO.IApplication> mock = new Mock<DTO.IApplication>();
mock.SetupProperty(f => f.Name, "Application");
mock.SetupProperty(f => f.ProjectId, 666);
mock.SetupProperty(f => f.ConfigFilePath, null);
DTO.IApplication appDto = mock.Object;
var entity = this.Mapper.Map<DTO.IApplication, Application>(appDto);
try
{
using var context = new GeneralContext(this.ContextOptions);
await context .ApplicationRepository.Add(entity);
}
catch (Exception ex)
{
var t = ex;
}
var one = 1;
var two = 2;
Assert.True(one != two);
}
我没有任何断言,这就是为什么要添加那个愚蠢的断言,但是当我通过上下文添加记录时,我得到了:
数据库提供者的服务'Microsoft.EntityFrameworkCore.InMemory','Npgsql.EntityFrameworkCore.PostgreSQL'已在服务提供者中注册。在服务提供商中只能注册一个数据库提供商。如果可能,请通过删除对UseInternalServiceProvider的调用来确保Entity Framework正在管理其服务提供商。否则,请考虑有条件地注册数据库提供者,或为每个数据库提供者维护一个服务提供者。
我已经按照MSDN上的文档进行了所有操作,所以这可能是错误的?
答案 0 :(得分:3)
optionsBuilder.UseNpgsql(config.GetConnectionString());
错误在这一行,这是控制反转的一个例子。您不应该在UseNpqSql
中调用OnConfiguring.
,这是因为它试图使用2个数据库。
this.ContextOptions = new DbContextOptionsBuilder<GeneralContext>()
.UseInMemoryDatabase(databaseName: "DiagAc2Tests")
.Options;
optionsBuilder.UseNpgsql(config.GetConnectionString());
以上两个语句都将运行。
现在的解决方案是将UseNpgsql移出配置之外,并移至应用程序启动类中。那当然取决于您的项目以及您如何实现它。
答案 1 :(得分:0)
在测试项目中,可以使用与应用程序不同的单独的Startup类,并且可以从内存中数据库中删除UseNpgsql。