我正在用模拟编写单元测试,但我无法成功编写它。其中一个属性是一个集合,我需要在为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; }
}
答案 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来教你这些东西)。