如何使用 Times() 方法为 RhinoMocks 中的方法调用设置 maximum/upper 绑定?
How to set a maximum/upper bound for method calls in RhinoMocks with the Times() method?
我正在尝试测试一个方法被调用了 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 次?
我不熟悉 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);
编辑:
只是为了扩展:
存根
存根是您不打算对其进行任何断言的对象。您使用存根插入方法 return 值的默认值,或存根调用 void
方法。
在存根对象上调用 .Verfiyxxxx
不会有任何效果,因为根据定义,存根不会跟踪该对象是如何交互的,它只知道 "When method x() is called, do this other action instead".
模拟
如果您希望断言与某个对象的交互,例如一个方法被调用了 4 次,或者一个方法被调用了一组特定的参数,那么你需要一个模拟对象。使用模拟需要调用 Expect
(这取决于您使用的模拟框架,但通常是 Expect
)
根据定义,存根不会检查期望值,另请参阅 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));
我正在尝试测试一个方法被调用了 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 次?
我不熟悉 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);
编辑:
只是为了扩展:
存根
存根是您不打算对其进行任何断言的对象。您使用存根插入方法 return 值的默认值,或存根调用 void
方法。
在存根对象上调用 .Verfiyxxxx
不会有任何效果,因为根据定义,存根不会跟踪该对象是如何交互的,它只知道 "When method x() is called, do this other action instead".
模拟
如果您希望断言与某个对象的交互,例如一个方法被调用了 4 次,或者一个方法被调用了一组特定的参数,那么你需要一个模拟对象。使用模拟需要调用 Expect
(这取决于您使用的模拟框架,但通常是 Expect
)
根据定义,存根不会检查期望值,另请参阅 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));