我正在尝试为使用我的EF Core DbContext
的类创建单元测试:
public class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options) : base(options)
{
}
public DbSet<SomeTable> SomeTables { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
}
}
使用该上下文的类很简单:
public class MyClass
{
public MyClass(MyContext db)
{
}
}
所以,当我尝试创建
var fakeContext = Substitute.For<MyContext>();
以错误结尾:
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: MyContext.
Could not find a parameterless constructor.
由base(options)
构造函数引发的。因此,最终的方法是扩展代码:
var dbContextOptions = Substitute.For<DbContextOptions<MyContext>>();
dbContextOptions.ContextType.Returns(typeof(MyContext));
var dbContextOptionsExtension = Substitute.For<IEnumerable<IDbContextOptionsExtension>>();
dbContextOptions.Extensions.Returns(dbContextOptionsExtension);
var myFakeContext = Substitute.For<MyContext>(dbContextOptions);
但是它会产生更多错误。那么,如何解决呢?
答案 0 :(得分:2)
您没有详细说明其他错误,因此我无法提供具体的答案,但是尝试正确地模拟DbContext很困难。 IMO有两种选择。
1)使用Microsoft in-memory provider。
2)如果要使用NSubstitute使用模拟的DbContext,请使用为您进行模拟的预先存在的库。诸如EntityFrameworkCore.Testing.NSubstitute之类的东西周围(免责声明-我是作者)。
内存提供程序不是完整的实现,它不能执行关系操作,并且不支持大量的LINQ操作,因此根据您的用例,后者可能是更好的解决方案。 / p>
如果您有特定的错误/用例,请将其弹出,我也许可以提供更好的答案。
答案 1 :(得分:1)
好的,我使用过InMemory
提供程序:
var options = new DbContextOptionsBuilder<AgreementContext>()
.UseInMemoryDatabase("fakeDb")
.Options;
var agreementContext = Substitute.For<MyContext>(options);