关于c#:Rhino Mocks:实例化Mock属性,以便Expectation可以引用它

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来教您这些东西)。