C# 如何在.NET Core应用程序中使用EntityFrameworkCore模拟DbContext
这个问题涉及如何在.NET Core应用程序中使用EntityFrameworkCore模拟DbContext。 以下是我的代码更改: 我的存储库类将使用DbContext与sqlserver通信并获取数据。 但是,在为我的存储库类编写单元测试时,我面临着与模拟DbContext和从DbSet()获取数据相关的问题 MyDbcontext重写OnModelCreating(),它包含必要的模型相关约束,如下所示 MyDbContext类:C# 如何在.NET Core应用程序中使用EntityFrameworkCore模拟DbContext,c#,.net,entity-framework,asp.net-core,mstest,C#,.net,Entity Framework,Asp.net Core,Mstest,这个问题涉及如何在.NET Core应用程序中使用EntityFrameworkCore模拟DbContext。 以下是我的代码更改: 我的存储库类将使用DbContext与sqlserver通信并获取数据。 但是,在为我的存储库类编写单元测试时,我面临着与模拟DbContext和从DbSet()获取数据相关的问题 MyDbcontext重写OnModelCreating(),它包含必要的模型相关约束,如下所示 MyDbContext类: public partial class myDbCo
public partial class myDbContext : DbContext
{
public myDbContext(DbContextOptions<myDbContext> options)
: base(options)
{
}
public virtual DbSet<Book> Books { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Books>(entity =>
{
entity.HasIndex(e => e.Name)
.HasName("BookNameIndex")
.IsUnique();
entity.Property(e => e.Id).ValueGeneratedNever();
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(256);
entity.Property(e => e.BookDescription)
.IsRequired()
.HasMaxLength(100);
});
}
}
公共部分类myDbContext:DbContext
{
公共myDbContext(DbContextOptions)
:基本(选项)
{
}
公共虚拟数据库集书籍{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity(Entity=>
{
entity.HasIndex(e=>e.Name)
.HasName(“书名索引”)
.IsUnique();
Property(e=>e.Id).ValueGeneratedNever();
entity.Property(e=>e.Name)
.IsRequired()
.HasMaxLength(256);
entity.Property(e=>e.BookDescription)
.IsRequired()
.HasMaxLength(100);
});
}
}
启动:
services.AddDbContext<myDbContext>(options => options.UseSqlServer(Settings.DatabaseConnectionString));
services.AddScoped(typeof(IBookRepository), typeof(BookRepository));
services.AddDbContext(options=>options.UseSqlServer(Settings.DatabaseConnectionString));
addScope(typeof(IBookRepository)、typeof(BookRepository));
我的班级
public class BookRepository : Repository<Book>, IBookRepository
{
public BookRepository(myDbContext context)
: base(context)
{
}
public void CreateBook(Book book)
{
if (!this.Exists(book.Id))
{
this.Insert(book);
}
}
}
public类BookRepository:Repository,IBookRepository
{
公共BookRepository(myDbContext上下文)
:基本(上下文)
{
}
公共书籍(书籍)
{
如果(!this.Exists(book.Id))
{
本.插入(书);
}
}
}
存储库:
公共类存储库,其中tenty:class
{
受保护的myDbContext-dataContext;
私营DbSet实体;
公共存储库(myDbContext上下文)
{
this.dataContext=context;
}
私有数据库集实体
{
得到
{
如果(实体==null)
{
//例外是在这里抛出
entities=dataContext.Set();
}
返回实体;
}
}
公共无效插入(TEntity实体)
{
if(实体==null)
{
抛出新的ArgumentNullException(“实体”);
}
实体。添加(实体);
dataContext.SaveChanges();
}
}
单元测试类别和方法:
[TestClass]
public class BookRepositoryTests
{
private readonly myDbContext _dbContext;
private readonly IBookRepository _BookRepository;
public BookRepositoryTests()
{
_dbContext = new InMemoryDbContextFactory().GetDbContext();
_BookRepository = new BookRepository(_dbContext);
}
[TestMethod]
public void TestMethod()
{
// Arrange
_dbContext.Book.Add(new Book());
_dbContext.SaveChanges();
// Act
_BookRepository.CreateBook(new Book());
}
}
public class InMemoryDbContextFactory
{
public myDbContext GetDbContext()
{
var options = new DbContextOptionsBuilder<myDbContext>()
.UseInMemoryDatabase(databaseName: "InMemoryArticleDatabase")
// and also tried using SqlLite approach. But same issue reproduced.
.Options;
var dbContext = new myDbContext(options);
return dbContext;
}
}
[TestClass]
公共类图书存储测试
{
私有只读mydbcontextu dbContext;
私有只读IBookRepository\u图书存储库;
公共图书存储测试()
{
_dbContext=新的InMemoryDbContextFactory().GetDbContext();
_BookRepository=新的BookRepository(_dbContext);
}
[测试方法]
公共void TestMethod()
{
//安排
_dbContext.Book.Add(newbook());
_dbContext.SaveChanges();
//表演
_BookRepository.CreateBook(newbook());
}
}
MemoryDBContextFactory中的公共类
{
公共myDbContext GetDbContext()
{
var options=new DbContextOptionsBuilder()
.UseInMemoryDatabase(数据库名称:“InMemoryArticleDatabase”)
//并尝试使用SqlLite方法,但同样的问题再次出现。
.选择;
var dbContext=新的myDbContext(选项);
返回dbContext;
}
}
在存储库类的Entities属性中观察到问题:
异常消息:
1.HasIndex(System.Linq.Expressions.Expression
1>)”有人能帮我解决这个问题吗?我遇到了同样的问题,我的问题是我测试项目中的ef core版本与我测试的版本不匹配(2.2.6 vs 3.1)。查看已安装的版本,确保它们都在同一版本上
我希望这对你也有帮助!干杯 我遇到了同样的问题,我的问题是我测试项目中的ef core版本与我测试的版本不匹配(2.2.6 vs 3.1)。查看已安装的版本,确保它们都在同一版本上
我希望这对你也有帮助!干杯 看起来您使用的是两个不同的实体。您的上下文引用了DbSet Books,但您的存储库引用的是一个Book实体。您在上下文中的声明是否不正确,是否应该是DbSet Books?更大的问题是,为什么要将存储库放在ef之上?ef已经实现了一个工作单元和存储库模式。我已经修改了代码。请再次查看,并建议我如何解决上述问题您不必模拟DbContext。您可以将其配置为在内存模式下使用内存中数据库或SQLite。检查您也不应该使用“通用”存储库。这对任何事情都没有帮助,但却增加了很多问题。例如,
SaveChanges
将在Insert
中进行多少更改以及进行何种更改?答案不得而知<代码>保存更改保存所有更改,而不仅仅是最后一个更改。检查Gunnar Peipman的,如果有任何问题,不需要的存储库可能是导致错误的原因myDbContext
已经包含所有类型的数据库集,但是存储库正试图通过调用.Set
来创建额外的DbSet
。看起来您使用的是两个不同的
[TestClass]
public class BookRepositoryTests
{
private readonly myDbContext _dbContext;
private readonly IBookRepository _BookRepository;
public BookRepositoryTests()
{
_dbContext = new InMemoryDbContextFactory().GetDbContext();
_BookRepository = new BookRepository(_dbContext);
}
[TestMethod]
public void TestMethod()
{
// Arrange
_dbContext.Book.Add(new Book());
_dbContext.SaveChanges();
// Act
_BookRepository.CreateBook(new Book());
}
}
public class InMemoryDbContextFactory
{
public myDbContext GetDbContext()
{
var options = new DbContextOptionsBuilder<myDbContext>()
.UseInMemoryDatabase(databaseName: "InMemoryArticleDatabase")
// and also tried using SqlLite approach. But same issue reproduced.
.Options;
var dbContext = new myDbContext(options);
return dbContext;
}
}