Mocking Entity Framework为我提供了未设置为对象实例的Object引用

时间:2016-06-07 13:03:18

标签: c# entity-framework unit-testing

我试图按照本指南模拟实体框架

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

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

  

对象引用未设置为对象的实例

我的目标非常简单:

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引发异常:

     

System.NullReferenceException:未将对象引用设置为对象的实例。

我不明白为什么指南中的代码运行正常,但我的代码并没有。

我已尝试添加虚拟&#39;到ID,标题和描述属性,但也没有做任何事情。有没有人知道对我来说可能有什么不同?

1 个答案:

答案 0 :(得分:3)

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

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); )未被模拟!