c# - 模拟 Entity Framework 给我对象引用未设置为对象的实例

标签 c# entity-framework unit-testing

我正在尝试按照本指南模拟 Entity Framework

https://msdn.microsoft.com/en-us/library/dn314429.aspx

当我在我的项目中构建指南中的代码时,它工作得非常好,但是当我试图将它应用到我的实际上下文和数据对象时,我遇到了一个异常:

Object reference not set to an instance of an object

我的对象很简单:

public class NodeAttributeTitle
{
    public int ID { get; set; }
    [MaxLength(150)]
    public string Title { get; set; }
    public string Description { get; set; }
}

我的背景是

public class DataContext : DbContext
{       
    public virtual DbSet<NodeAttributeTitle> NodeAttributeTitles { get; set; }          
}   

我尝试设置的方法只是一个基本的插入

public class CommonNodeAttributes : ICommonNodeAttributes
{
    private DataContext _context;

    public CommonNodeAttributes(DataContext context)
    {
        _context = context;
    }

    public CommonNodeAttributes()
    {
        _context = new DataContext();
    }

    public void Insert(string value)
    {
        var nodeAttributeValue = new NodeAttributeValue();

        nodeAttributeValue.Value = value;
        nodeAttributeValue.Parent = 0;

        _context.NodeAttributeValues.Add(nodeAttributeValue);
        _context.SaveChanges();
    }
}

并且测试类遵循与 MSDN 指南中相同的语法

[TestClass]
public class CommonNodeAttributesTests
{
    [TestMethod]
    public void CreateNodeAttribute_saves_a_nodeattribute_via_context()
    {
        var mockSet = new Mock<DbSet<NodeAttributeTitle>>();
        var mockContext = new Mock<DataContext>();
        mockContext.Setup(m => m.NodeAttributeTitles).Returns(mockSet.Object);
        var service = new CommonNodeAttributes(mockContext.Object);
        service.Insert("blarg");
        mockSet.Verify(m => m.Add(It.IsAny<NodeAttributeTitle>()),Times.Once());
        mockContext.Verify(m => m.SaveChanges(),Times.Once);

    }
}   

但是当测试运行时,我得到了

Tests.CommonNodeAttributesTests.CreateNodeAttribute_saves_a_nodeattribute_via_context threw exception:

System.NullReferenceException: Object reference not set to an instance of an object.

我不明白为什么指南中的代码可以正常工作,但我的代码却不行。

我已经尝试将“虚拟”添加到 ID、标题和描述属性,但这也没有任何作用。有谁知道对我来说可能有什么不同?

最佳答案

您需要在模拟中提供一些数据:

IQueryable<NodeAttributeTitle> data = new List<NodeAttributeTitle>
{
    new NodeAttributeTitle() {Id = 1, Title = "t1"},
    new NodeAttributeTitle() {Id = 2, Title = "t2"},
}.AsQueryable();
var mockSet = new Mock<IDbSet<NodeAttributeTitle>>();
mockSet .Setup(m => m.Provider).Returns(data.Provider);
mockSet .Setup(m => m.Expression).Returns(data.Expression);
mockSet .Setup(m => m.ElementType).Returns(data.ElementType);
mockSet .Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

然后您可以将它传递给您的 DbContext:

您在代码中的问题在于 Add 方法(_context.NodeAttributeValues.Add(nodeAttributeValue);)未被模拟!

关于c# - 模拟 Entity Framework 给我对象引用未设置为对象的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37680210/

相关文章:

c# - Form.Owner - 拥有的表单不递归关闭/隐藏

c# - 如何按表列过滤 LINQ 查询并获取计数

c# - EF vs SQL 奇怪的慢

reactjs - Jest : setTimeout is being called too many times

c# - 在不显示对话框的情况下保存文件

c# - 一个具有多个项目的 asp.net web 应用程序作为一个团队开发,轻松更新!

c# - 更改我的对象列表上的顺序

c# - 如何使用 Entity Framework Code First Fluent API 仅在连接表上级联删除

javascript - 在 Controller 中进行单元测试 $http 解析

c# - 断言后如何获取异常对象?