我试图测试方法被调用3到4次:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using StructureMap.AutoMocking;
namespace AutoMockPlayground
{
[TestClass]
public class SomeTests
{
[TestMethod]
public void Bara_ShouldBeCalledThreeOrFourTimes()
{
var autoMocker = new RhinoAutoMocker<Foo>(MockMode.AAA);
var barMock = autoMocker.Get<IBar>();
// Bara() should not be called more than four times
barMock.Stub(bar => bar.Bara()).Repeat.Times(3, 4);
autoMocker.ClassUnderTest.DoSomeThing();
barMock.VerifyAllExpectations();
}
}
public interface IBar
{
void Bara();
}
public class Foo
{
private readonly IBar _bar;
public Foo(IBar bar)
{
_bar = bar;
}
public void DoSomeThing()
{
_bar.Bara();
_bar.Bara();
_bar.Bara();
_bar.Bara();
_bar.Bara();
}
}
}
我使用Repeat.Times(int min, int max)
,但max
参数似乎没有任何效果。
虽然Bara()
被调用了5次,但是这个测试通过了。
我如何在测试中表达Bara()
应该被调用3到4次?
答案 0 :(得分:1)
我不熟悉RhinoAutoMocker
,但看起来barMock
被用作存根对象而不是模拟对象。
如果它是存根(即使用.Stub()),那么调用VerifyAllExpectations()
将不起作用。相反,它需要是一个模拟对象,调用VerifyAllExpectations()
应该可以工作。
例如,这是我在测试中使用模拟的方法。
var mockObject = MockRepository.GenerateMock<IFoo>();
mockObject.Expect(o => o.CallSomething().Repeat.Times(1);
mockObject.VerifyAllExpecttions();
所以而不是
barMock.Stub(bar => bar.Bara()).Repeat.Times(3, 4);
barMock.Expect(bar => bar.Bara()).Repeat.Times(3, 4);
编辑:
只是为了扩展:
<强>存根强>
存根是一个你不打算断言任何东西的对象。您可以使用存根来插入方法返回值的默认值,或者对void
方法的调用进行存根。
在存根对象上调用.Verfiyxxxx
将没有任何效果,因为根据定义,存根不会跟踪该对象的交互方式,它只是知道&#34;当调用方法x()时,做其他行动而不是&#34;。
<强>模拟强>
如果您希望断言与对象的交互,例如一个方法被调用了4次,或者一个方法被一组特定的参数调用,那么你需要一个模拟对象。使用模拟需要调用Expect
(这取决于您正在使用的模拟框架,但它通常是Expect
)
答案 1 :(得分:1)
根据定义,存根不会检查期望,另请参阅this
但是,您只需拨打AssertWasCalled
即可验证期望
您可以按如下方式修改代码:
var autoMocker = new RhinoAutoMocker<Foo>(MockMode.AAA);
var barMock = autoMocker.Get<IBar>();
autoMocker.ClassUnderTest.DoSomeThing();
// Bara() should not be called more than four times
barMock.AssertWasCalled(bar => bar.Bara(),
options => options.IgnoreArguments().Repeat.Times(3,4));