使用Rhino Mocks返回空列表作为默认值

时间:2009-02-12 07:52:02

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

我认为总是返回空列表或数组而不是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 );

3 个答案:

答案 0 :(得分:0)

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

你可能总是很棘手并且通过成员进行枚举,检查ILists / Arrays并动态设置模拟 - 这取决于你有多少类型与你可以为这个实用方法专用的类型。

祝你好运!

答案 1 :(得分:0)

事实证明,只要返回的对象是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 :(得分:-1)

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

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

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

为什么呢?因为碰到ICustomerRepository的类没有正确处理空值。

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