查询 Mocked Entity Framework 上下文的异常
Exception querying a Mocked Entity Framework Context
当我使用 MockBehavior.Strict 创建 Mock 实例时,出现错误
'Moq.MockException' 类型的异常发生在 Moq.dll 但未在用户代码中处理
附加信息:DbContext.Set() 调用因模拟行为 Strict 而失败。
模拟上的所有调用都必须具有相应的设置。
但我已经为每一个 table 设置好了,包括那个:
var mockContext = new Mock<JournalsDB>(MockBehavior.Strict);
mockContext.Setup(m => m.Publications).Returns(mockPublicationSet.Object);
mockContext.Setup(m => m.Journals).Returns(mockJournalSet.Object);
mockContext.Setup(m => m.AspNetUsers).Returns(mockUserSet.Object);
mockContext.Setup(m => m.AspNetRoles).Returns(mockRoleSet.Object);
mockContext.Setup(m => m.AspNetUserClaims).Returns(mockClaimSet.Object);
mockContext.Setup(m => m.AspNetUserLogins).Returns(mockLoginSet.Object);
我怀疑问题可能与我的存储库实现或 DbContext 实现有关:
public class JournalRepository<DataObject, DataContext> : IRepository<DataObject, DataContext>, IDisposable
where DataObject : class
where DataContext : DbContext
{
#region Propiedades
private readonly DataContext _ctx;
等...
public partial class JournalsDB : DbContext
{
public JournalsDB()
: base("name=JournalsDB")
{
}
public JournalsDB(string connectionName)
: base(connectionName)
{
}
等...
编辑:
没有 MockBehaviour.Strict 我得到错误值不能为空。参数名称:查询任何 DbSet 但正确填充 DbSet 时的来源。
老实说,我真的认为你在这里采取了错误的方法。模拟 DbContext
真的很痛苦,因为那是一个非常宽的接口。这实际上是一个尝试虚拟化您不拥有的接口的情况。模仿别人的界面总是自找麻烦。在 DbContext
的情况下,您真的还想模拟 SaveChanges()
.
等调用的行为
我会将 DbContext
的用法隔离在一个更易于模拟的小得多的接口后面。然后,您将有两种类型的测试要编写:
对使用新界面的任何内容进行单元测试。这些测试将更容易编写,因为您不必伪造 DbContext
使用包含真实数据的真实数据库测试 实现 接口的 class。这样,您就可以单独测试数据访问层。
更详细的解释看我这里写的答案:
当我使用 MockBehavior.Strict 创建 Mock 实例时,出现错误
'Moq.MockException' 类型的异常发生在 Moq.dll 但未在用户代码中处理
附加信息:DbContext.Set() 调用因模拟行为 Strict 而失败。
模拟上的所有调用都必须具有相应的设置。
但我已经为每一个 table 设置好了,包括那个:
var mockContext = new Mock<JournalsDB>(MockBehavior.Strict);
mockContext.Setup(m => m.Publications).Returns(mockPublicationSet.Object);
mockContext.Setup(m => m.Journals).Returns(mockJournalSet.Object);
mockContext.Setup(m => m.AspNetUsers).Returns(mockUserSet.Object);
mockContext.Setup(m => m.AspNetRoles).Returns(mockRoleSet.Object);
mockContext.Setup(m => m.AspNetUserClaims).Returns(mockClaimSet.Object);
mockContext.Setup(m => m.AspNetUserLogins).Returns(mockLoginSet.Object);
我怀疑问题可能与我的存储库实现或 DbContext 实现有关:
public class JournalRepository<DataObject, DataContext> : IRepository<DataObject, DataContext>, IDisposable
where DataObject : class
where DataContext : DbContext
{
#region Propiedades
private readonly DataContext _ctx;
等...
public partial class JournalsDB : DbContext
{
public JournalsDB()
: base("name=JournalsDB")
{
}
public JournalsDB(string connectionName)
: base(connectionName)
{
}
等...
编辑:
没有 MockBehaviour.Strict 我得到错误值不能为空。参数名称:查询任何 DbSet 但正确填充 DbSet 时的来源。
老实说,我真的认为你在这里采取了错误的方法。模拟 DbContext
真的很痛苦,因为那是一个非常宽的接口。这实际上是一个尝试虚拟化您不拥有的接口的情况。模仿别人的界面总是自找麻烦。在 DbContext
的情况下,您真的还想模拟 SaveChanges()
.
我会将 DbContext
的用法隔离在一个更易于模拟的小得多的接口后面。然后,您将有两种类型的测试要编写:
对使用新界面的任何内容进行单元测试。这些测试将更容易编写,因为您不必伪造
DbContext
使用包含真实数据的真实数据库测试 实现 接口的 class。这样,您就可以单独测试数据访问层。
更详细的解释看我这里写的答案: