简体   繁体   English

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

[英]Rhino Mocks: Instantiating Mock property so Expectation can reference it

I'm writing a unit test with a mock and I'm having trouble writing it successfully.我正在使用模拟编写单元测试,但无法成功编写它。 One of the properties is a collection and I need to reference it when setting an expectation for the mock.其中一个属性是一个集合,我需要在为模拟设置期望时引用它。 Right now the expectation statement throws a null.现在期望语句抛出 null。 Here's what it roughly looks like.这是它大致的样子。

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

I'm new to rhino mocks and have a feeling I'm not doing this correctly.我是犀牛模拟的新手,感觉我做的不对。 Is there anyway else to properly instantiate the collection?还有其他方法可以正确实例化集合吗? Possibly without an expectation like I have above?可能没有像我上面那样的期望?

Update更新
I think I'm having the problem because the interface I defined specifies the collection as readonly.我认为我遇到了问题,因为我定义的接口将集合指定为只读。

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

I'm not overly familiar with Rhino Mocks, but I think your expectations aren't actually hooked up until you call .Replay() - the mocking methodology you hint at in your example looks more like Moq to me.我对 Rhino Mocks 并不太熟悉,但我认为在您调用.Replay()之前,您的期望实际上并没有关联 - 您在示例中暗示的 mocking 方法对我来说更像是Moq

That said, I think you're doing something more fundamentally wrong here.就是说,我认为您在这里做的事情根本上是错误的。 Exactly what is it that you want to test?你到底想测试什么? Is it the p object, or something on List<Entity> ?p object,还是List<Entity>上的东西? If what you actually want to test is that p.YourMethodUnderTest() actually adds entity to the collection, you probably just want to setup p.FooCollection to return your list, and then verify that your list contains the entity object.如果您真正想要测试的是p.YourMethodUnderTest()确实将entity添加到集合中,您可能只想设置p.FooCollection以返回您的列表,然后验证您的列表是否包含实体 object。

// 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

Instead of mocks you should use stubs, like:您应该使用存根而不是模拟,例如:

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

Also, you are setting the expectation on a real object (collection.Add()), which won't really work.此外,您将期望设置在真正的 object (collection.Add()) 上,这不会真正起作用。 You can solve this by making your FooCollection property type of IList instead of a concrete List .您可以通过将FooCollection属性类型设置为IList而不是具体的List来解决此问题。

Using concrete collection types as parameters is a code smell anyway (and I suggest using FxCop to teach you such things).无论如何,使用具体的集合类型作为参数是一种代码味道(我建议使用 FxCop 来教你这些东西)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM