Rhino Mocks:实例化Mock属性,以便Expection可以引用它

本文关键字:Expection 引用 以便 Mocks 实例化 Mock 属性 Rhino | 更新日期: 2023-09-27 17:58:40

我正在用mock编写一个单元测试,但我很难成功地编写它。其中一个属性是集合,我需要在设置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; }
}

Rhino Mocks:实例化Mock属性,以便Expection可以引用它

我对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

您应该使用存根而不是mock,比如:

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

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

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