【问题标题】:Returning empty lists as default with Rhino Mocks使用 Rhino Mocks 默认返回空列表
【发布时间】:2010-10-07 03:00:53
【问题描述】:

我认为总是返回空列表或数组而不是 null 是一个好习惯 当一个方法没有结果时避免代码中的空检查。

因为 Rhino Mocks 返回一个对象的默认值,对于列表和数组,它是 null,很多时候我必须重新添加 null 检查或设置模拟以返回列表。

有没有办法使用这种行为来配置或扩展 Rhino Mocks?

var repositoryMock = MockRepository.GenerateMock<ICustomerRepository>();
IList<Customer> customers = repositoryMock.getCustomers();

Assert.IsNotNull(customers);
Assert.AreEqual(0, customers.Count );

【问题讨论】:

    标签: c# unit-testing tdd rhino-mocks moq


    【解决方案1】:

    事实证明,只要返回的对象是 IEnumerable,Moq 就可以实现这种行为。以下测试通过:

    [Test]
    public void EmptylListTest()
    {
        var repositoryMock = new Mock<ICustomerRepository>();
    
        IEnumerable<Customer> customers = repositoryMock.Object.GetCustomers();
    
        Assert.IsNotNull(customers);
        Assert.AreEqual(0, customers.Count());
    }
    
    [Test]
    public void EmptyArrayTest()
    {
        var repositoryMock = new Mock<ICustomerRepository>();
    
        Customer[] customerArray = repositoryMock.Object.GetCustomerArray();
    
        Assert.IsNotNull(customerArray);
        Assert.AreEqual(0, customerArray.Length);
    }
    
    public interface ICustomerRepository
    {
        IEnumerable<Customer> GetCustomers();
        Customer[] GetCustomerArray();
    }
    

    【讨论】:

      【解决方案2】:

      我认为更改模拟的默认行为以返回非默认值将是一个冒险的举动。

      如果您的 ICustomerRepository 的实际实现中有一个错误,导致它没有返回空列表而是返回 null,会发生什么?

      如果您编写了其他单元测试并针对自动返回空列表的 ICustomerRepository 的模拟版本进行了测试,那么您会认为一切正常。您甚至可能构建该代码并认为它​​会正常工作,因此您运行编译后的应用程序并开始崩溃。

      为什么?因为您命中 ICustomerRepository 的类没有正确处理空值。

      我宁愿明确并在测试中设置期望从 getCustomers() 方法返回一个空的 IList,而不是在模拟中发生一些“魔术”。为什么?因为它提高了可读性,并且代码的工作方式与其他可能不熟悉 rhino 的开发人员所期望的工作方式一致。即没有期望的方法返回默认值。

      【讨论】:

      • 如果 ICustomerRepository 返回 null,应用程序将崩溃是一个有效点,但这是存储库的错误,而不是使用它的类。我会(希望 :))对存储库进行单元测试以解决该问题。
      • 我可以忍受一个比平时更神奇的模拟:)。我宁愿让它们像系统的其他部分一样发挥作用。感谢您的意见!
      【解决方案3】:

      Rhino Mocks 没有任何功能可以自动解决您的问题。最简单的解决方案是简单地为使用 SetupResult(或 repeat.any)的每种类型设置一个扩展/实用方法来配置默认值。

      您总是很棘手并通过成员进行枚举,检查 ILists / Arrays 并动态设置模拟 - 这取决于您拥有多少类型以及您可以为此实用程序方法专用多少类型。

      祝你好运!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-01
        • 1970-01-01
        相关资源
        最近更新 更多