c# - 如何使用 Rhino 模拟 stub SingleOrDefault

标签 c# unit-testing entity-framework-4 rhino-mocks

我很难理解我的方法是否正确。我想测试一个存储库。存储库依赖于 DbContext。我希望能够验证存储库没有在作为 DbContext 成员的 IDbSet 类型的属性上调用函数 Add。

我尝试了两种方法。用行为验证,用状态验证。似乎验证行为是正确的,因为谁知道 stub 状态在假对象中做了什么。

    public void VerifyBehaviour()
    {
        // Arrange
        var stubEntities = MockRepository.GenerateStub<IWsStatContext>();
        var stubManufcturers = MockRepository.GenerateStub<IDbSet<Manufacturer>>();
        var manufacturer = new Manufacturer() { Name = "Dummy" };
        var manufacturers = new List<Manufacturer>();
        manufacturers.Add(manufacturer);

        stubManufcturers.Stub(x => x.Local).Return(new System.Collections.ObjectModel.ObservableCollection<Manufacturer>(manufacturers));
        stubManufcturers.Stub(x => x.SingleOrDefault(m => m.Name == "Dummy")).Return(manufacturer);
        stubEntities.Manufacturers = stubManufcturers;

        // Act
        var sut = new EquiptmentRepository(stubEntities);
        sut.AddManufacturer(manufacturer);

        // Assert
        stubManufcturers.AssertWasNotCalled(x => x.Add(manufacturer));
    }


    public void VerifyState()
    { 
        // Arrange
        var stubEntities = MockRepository.GenerateStub<IWsStatContext>();
        var stubManufacturers = new InMemoryDbSet<Manufacturer>();
        var manufacturer = new Manufacturer() { Name = "Dummy" };
        stubManufacturers.Add(manufacturer);
        stubEntities.Manufacturers = stubManufacturers;

        // Act
        var sut = new EquiptmentRepository(stubEntities);
        sut.AddManufacturer(manufacturer);

        // Assert
        Assert.AreEqual(stubManufacturers.Count(), 1);
    }

验证行为方法因 SingleOrDefault stub 周围的 NullReferenceExceptions 而失败。所以我发现帖子说最好验证状态并使用伪造的 DbSet。但是检查假对象的状态感觉不对。如果 Add 函数的实现方式与真实函数不同(它最初是这样的,即使我的存储库已损坏,我的测试也通过了)怎么办?

有谁知道如何 stub SingleOrDefault 以便我可以检查 Add 是否被调用?我无法检查 Add 是在非 rhinomocked stub 上调用的。

谢谢

最佳答案

jimmy_keen's answer 中所述:

SingleOrDefault is an extension method defined on IEnumerable<T> (which IDbSet<T> implements). Being extension method means it is a static method. RhinoMocks (or any other free tool) cannot mock/stub static methods.

与其尝试“ stub ”扩展方法,不如尝试 stub 扩展方法所基于的底层接口(interface):IEnumerable<T>

stubManufcturers.Stub( x => x.GetEnumerator() ).Return( new List<Manufacturer> { manufacturer }.GetEnumerator() );

通过标记 GetEnumerator() 的行为什么时候SingleOrDefault被调用时,它将按预期针对虚假枚举执行,并且测试将能够评估行为。

关于c# - 如何使用 Rhino 模拟 stub SingleOrDefault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10525019/

相关文章:

swift - UINavigationController 释放测试失败?

javascript - 如何在 Jest 中的同一测试套件中的测试之间清除模块模拟?

sql-server - 插入到具有而不是来自实体数据框架的触发器的表中时出错

c# - 从 URL 打开 XmlDocument

c# - 消除删除空目录算法中的递归

javascript - 开始安装 Karma 和 Jasmine - jasmine.Suite() 需要错误

linq - EF如何按日期过滤数据

.net - 如何将 TransactionScope 与 MySql 和 Entity Framework 一起使用? (获取多个同时连接...当前不支持错误)

c# - WPF 日历周末着色

c# - 如何使用 Asp.net Websrvice 绑定(bind) ExtJS 网格?