Rhino Mocks: Instantiating Mock property so Expectation can reference it
我正在用一个mock编写一个单元测试,但在成功编写它时遇到了问题。其中一个属性是集合,我需要在为模拟设置期望值时引用它。现在,期望语句抛出一个空值。这就是它大致的样子。
1 2 3 4 5 6
| 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 |
我对犀牛嘲弄还不太熟悉,感觉自己做得不对。是否还有其他方法可以正确实例化集合?可能没有我上面的期望?
更新我认为我遇到了问题,因为我定义的接口将集合指定为只读。
1 2 3 4
| interface IFoo
{
List<Entity> FooCollection { get; }
} |
我对犀牛模型并不太熟悉,但我认为你的期望在你给.Replay()打电话之前并没有实现——你在例子中提到的模拟方法在我看来更像moq。
也就是说,我认为你在做一些更根本的错误。你到底想测试什么?它是p对象,还是List上的东西?如果您实际想要测试的是p.YourMethodUnderTest()实际将entity添加到集合中,那么您可能只需要设置p.FooCollection返回列表,然后验证您的列表是否包含实体对象。
1 2 3 4 5 6 7 8 9 10 11 12 13
| // 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 2
| IFoo myMock = MockRepository.GenerateStub<IFoo>();
myMock.FooCollection = col; |
另外,您正在对一个实际对象(collection.add())设置期望值,但这并不真正起作用。您可以通过使您的FooCollection属性类型为IList,而不是具体的List来解决这个问题。
无论如何,使用具体的集合类型作为参数都是一种代码味道(我建议使用fxcop来教您这些东西)。
- 集合是只读的,因此您不能像在示例中那样直接分配它。是因为我将集合公开为属性而引起的代码味道吗?我可以看到将其保留为私有字段并添加addentity()方法是有益的,因为现在我回顾一下我的代码,在将其添加到集合后,客户机代码与实体进行处理的地方存在耦合代码。
- 关于只读集合,您是对的,我的代码不起作用。至于代码气味,我的意思是:stackoverflow.com/questions/387937/&hellip;
- 我不确定我是否完全同意这个问题的主要答案,但我认为我需要避免曝光我的收藏。回答中提到,list是膨胀的,ilist不是膨胀的。嗯,是的,应该是这样的。您的ilist变量仍然指向一个列表,因此它不会"膨胀"。
- 通过公开IList<>实际上使实现更容易使用List<>以外的东西,例如Entity[]数组。其思想是使用接口来定义合同,而不是在这些合同中强制执行实现细节。指定一个具体的集合类型(如List)正在强制执行一个实现细节,而不需要实际的需求。通过使用接口,你实际上可以更容易地模拟事物。
- 至于你对AddEntity()方法的建议,不是公开收集,是一个很好的建议。见德米特定律(en.wikipedia.org/wiki/law-of-demeter)
- 谢谢你的观点。我想我昨天作为一个开发者成长了一点:)