为什么我的模拟上下文中的 DbSet 为空?

如何解决为什么我的模拟上下文中的 DbSet 为空?

最近,我一直在尝试研究 C# 中的单元测试和模拟。对于我选择的工具,我一直使用 Nunit 作为我的测试框架,AutoFac 作为我的 IoC 容器,Moq 用于模拟 DB,以及 Entity Framework 6 用于与所述 DB 对话。

在我的单元测试中,为了判断我是否可以从模拟数据库成功加载,我收到了 NullReferenceException - 在我的模拟数据库中找不到我要查找的对象。

通过逐步完成我的测试,我能够确定我的 mockSet 以及我的 MockContext 确实有我在其中设置的测试记录。

Automock 还能够成功创建我正在测试的类的对象,并将测试方法所依赖的上下文的实例传递给它。但是,此上下文实例中的 DbSet 均显示为 null,从而导致我的 Find() 函数失败。

Image displays that the Character DbSet within the the data root implementation is null.

我不确定为什么我的实现中的 DbSet 字符集为空。据我了解,在创建我的 mockSet 和 mockContext 之后,AutoMock 应该检测并将我的 mockContext 注入到在此单元测试期间调用我的上下文的任何内容中。不是这样吗?如果是这样,是什么情况?我要采取什么步骤来确保我正在测试的类注入了我的 mockContext 实例?

这是我的单元测试:

[Test]
public void MysqLDaTaroot_LoadCharacterByCharacterID_SingularCharacterObjectReturned()
{
    using (var mock = AutoMock.GetLoose())
    {
        //Attain
        //When my code that I'm testing calls for a CharacterContext,return the mock instead.
        //Currently,this mock only has a table for Characters set up. trying to get other tables will fail.

        //1. Create data to be set in the mock set.
        //Tested and confirmed that my test record is being placed into my mockSet and mockContext properly.
        List<Character> charList = new List<Character>();
        charList.Add(getSampleCharacter());
        IQueryable<Character> data = charList.AsQueryable();

        //2. Create mock set.
        var mockSet = new Mock<DbSet<Character>>();
        mockSet.As<IQueryable<Character>>().Setup(m => m.Provider).Returns(data.Provider);
        mockSet.As<IQueryable<Character>>().Setup(m => m.Expression).Returns(data.Expression);
        mockSet.As<IQueryable<Character>>().Setup(m => m.ElementType).Returns(data.ElementType);
        mockSet.As<IQueryable<Character>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

        //3. Create a context based upon the mockSet
        var mockContext = new Mock<CharacterContext>();
        mockContext.Setup(c => c.Characters).Returns(mockSet.Object);

        //Act
        //DaTaroot is created and has a _characterContext,but the Characters DbSet is null.
        var daTaroot = mock.Create<MysqLDaTaroot>();
        var expected = getSampleCharacter();
        var actual = daTaroot.GetCharacterBy_CharacterID(Guid.Parse("11111111-2222-3333-4444-555555555555"));

        //Assert
        Assert.True(actual != null);
        Assert.AreEqual(expected.Character_id,actual.Character_id);        
    }
}

解决方法

我认为问题在于您在第 3 步创建的模拟 CharacterContext 与模拟 MySqlDataRoot 不同。我没有看到任何可以确保它是同一个实例的东西。再说一次,我不使用自动模拟功能,所以我不熟悉它通常是如何工作的。

,

找到解决方案,感谢 Plasmadog 指出我的错误,以及 Shafiq Jetha 的回答 here

我遇到的问题是双重的:首先,正如 Plasmadog 在他的回答中指出的那样,我没有使用我认为已经通过的相同的模拟上下文。

其次,我缺少 EntityFrameworkTesting.Moq 包,以及 Shafiq 指出的一些关键功能。

对于将来找到此答案的任何人,这里是对我有用的解决方案。

[Test]
public void MySqlDataRoot_LoadCharacterByCharacterID_SingularCharacterObjectReturned()
{

    //Arrange
    //1. Create the test data.
    List<Character> charList = new List<Character>();
    charList.Add(getSampleCharacter());

    //2. Create a mock set,one that properly responds to EntityFramework's .Find()
    var mockSet = new Mock<DbSet<Character>>()
        .SetupData(charList,o =>
        {
            return charList.Single(x => x.Character_id.CompareTo(o.First()) == 0);
        });

    using (var mockContext = AutoMock.GetLoose())
    {
        //Act
        //3. Use the mockSet to properly create the mockContext.
        mockContext.Mock<CharacterContext>().Setup(x => x.Characters).Returns(mockSet.Object);

        //4. Create a instance of MySqlDataRoot,injecting mock via the constructor.
        IDataRoot toTest = mockContext.Create<MySqlDataRoot>();
        var expected = getSampleCharacter();
        var Actual = toTest.GetCharacterBy_CharacterID(expected.Character_id);


        //Assert
        Assert.IsNotNull(expected);
        Assert.IsNotNull(Actual);
        Assert.AreEqual(Actual.Character_id,expected.Character_id);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?