Rhino Mocks:实例化Mock属性,因此Expectation可以引用它

时间:2011-06-07 19:31:34

标签: c# unit-testing rhino-mocks

我正在用模拟编写单元测试,但我无法成功编写它。其中一个属性是一个集合,我需要在为mock设置期望时引用它。现在期望语句抛出null。这是它大致的样子。

IFoo myMock = MockRepository.GenerateMock<IFoo>();
List<Entity> col = new List<Entity>();
Entity entity = new Entity();

myMock.Expect(p => p.FooCollection).Return(col);
myMock.Expect(p => p.FooCollection.Add(entity)); // throws null exception here

我是犀牛嘲笑的新手,并且有一种感觉我没有正确地做到这一点。还有其他方法来正确实例化集合吗?可能没有我上面的期望吗?

更新
我想我遇到了问题,因为我定义的接口将集合指定为只读。

interface IFoo
{
    List<Entity> FooCollection { get; }
}

2 个答案:

答案 0 :(得分:1)

我对Rhino Mocks并不过分熟悉,但我认为在你调用.Replay()之前,你的期望并非实际连接 - 你在示例中提示的模拟方法更像是Moq给我。

那就是说,我认为你在这里做了一些更根本的错误。究竟你想测试什么?它是p对象,还是List<Entity>上的某个对象?如果您真正要测试的是p.YourMethodUnderTest()实际上将entity添加到集合中,您可能只想设置p.FooCollection以返回列表,然后验证您的列表是否包含实体对象

// Arrange
IFoo myMock = MockRepository.GenerateMock<IFoo>();
List<Entity> col = new List<Entity>();
Entity entity = new Entity();

myMock.Expect(p => p.FooCollection).Return(col);
// myMock.Expect(p => p.FooCollection.Add(entity)) - skip this

// Act
p.YourMethodUnderTest(entity);

// Assert
Assert.IsTrue(col.Contains(entity)); // Or something like that

答案 1 :(得分:0)

您应该使用存根,而不是模拟,例如:

IFoo myMock = MockRepository.GenerateStub<IFoo>();
myMock.FooCollection = col;

此外,您正在设置真实对象(collection.Add())的期望,这不会真正起作用。您可以通过将FooCollection属性类型IList设置为具体List来解决此问题。

使用具体的集合类型作为参数无论如何都是代码味道(我建议使用FxCop来教你这些东西)。