53

我有一个模拟对象,它作为构造函数参数传递给另一个对象。

如何测试已调用模拟对象的属性?这是我目前使用的代码:

INewContactAttributes newContact = MockRepository.GenerateMock<INewContactAttributes>();
newContact.Stub(x => x.Forenames).Return("One Two Three");
someobject.ConsumeContact(newContact);
newContact.AssertWasCalled(x => { var dummy = x.Forenames; });

这有效,除非在“someobject”内多次使用 Forenames 属性的 getter。那是我得到“Rhino.Mocks.Exceptions.ExpectationViolationException: INewContactAttributes.get_Forenames(); 预期 #1,实际 #2 ..”的时候

只需使用

newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.Any());

不起作用并给出以下错误:

“期望已从等待期望列表中删除,您是否调用了 Repeat.Any() ? AssertWasCalled() 不支持此操作。”

那么如何满足多个呼叫的需求呢?

4

6 回答 6

76

newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.AtLeastOnce());

Repeat.Any不起作用,AssertWasCalled因为 0 算作任何......所以如果它没有被调用,AsserWasCalled即使它没有被调用,也会返回 TRUE。

于 2009-06-19T23:45:14.550 回答
28

我同意克里斯的回答

newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.AtLeastOnce());

此外,如果您确切知道该属性将被调用多少次,您可以这样做

newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.Times(n));

其中 n 是一个整数。

于 2010-07-16T12:16:44.593 回答
2

你检查它被调用的次数背后的动机是什么?这是一项特别昂贵的手术吗?如果是这样,那么我建议您将其放在方法后面,因为从语义上讲,属性应该是廉价的调用。

此外,检查属性被调用的次数并不是单元测试的重点(不要担心测试太多是一个常见的错误,我们都经历过)。您真正应该测试的是,给定模拟对象的状态,该方法会产生预期的输出。调用方法的次数并不重要(除非它是发送电子邮件或其他东西的服务)。这是一个你通常不会测试的实现细节,因为简单的重构会破坏你的测试,因为它们太具体了。

于 2009-04-08T09:48:35.033 回答
2

根据您使用的 Rhino 版本,您可以使用:

// Call to mock object here
LastCall.IgnoreArguments().Repeat.Never();
于 2009-09-07T20:40:49.787 回答
0

newContact.Expect(c => c.ForeNames).Return(...).Repeat.Any()

于 2009-04-08T09:50:59.630 回答
0

这里

mock.AssertWasCalled(x => x.Name ="Bob");

或者

mock.AssertWasCalled(x => x.Name =Arg.Is("Bob"));

或者

mock.AssertWasCalled(x => x.Name =Arg<string>.Is.NotNull);
于 2011-10-11T14:02:39.340 回答