RhinoMocks VerifyAllExpectations 对存根方法的多个 Expects 失败
RhinoMocks VerifyAllExpectations fails for multiple Expects on stubbed method
亲爱的 RhinoMocks 用户。我是 RhinoMocks 的新手,在思考问题时遇到了问题。我需要在 class 中测试两个方法,其中一个调用另一个多次。我已经分别测试了多次调用的方法,设置有些复杂,所以测试另一种方法的想法是对已经测试过的方法进行存根。这是一个最小的例子:
public class TestedClass
{
public virtual void DoSthOnce(List<int> listParam)
{
foreach (var param in listParam)
DoSthMultipleTimes(param);
}
public virtual void DoSthMultipleTimes(int intParam)
{
Console.WriteLine("param: " + intParam);
}
}
即DoSthMultipleTimes()
已经过测试。以下测试代码有效并验证是否为作为参数提供给 DoSthOnce()
.
的列表的每个元素调用了 DoSthMultipletimes()
-Method
var paramList = Enumerable.Range(1, 10).ToList();
var mock = MockRepository.GeneratePartialMock<TestedClass>();
mock.Stub(m => m.DoSthMultipleTimes(Arg<int>.Is.Anything))
.WhenCalled(mi =>
{
// Only for debug; this method is empty in the actual test code.
Console.WriteLine("Stub called with " + mi.Arguments[0]);
});
mock.DoSthOnce(paramList);
// This will not throw an exception
foreach (var param in paramList)
mock.AssertWasCalled(m => m.DoSthMultipleTimes(param));
输出符合预期:
Stub called with 1
Stub called with 2
Stub called with 3
Stub called with 4
Stub called with 5
Stub called with 6
Stub called with 7
Stub called with 8
Stub called with 9
Stub called with 10
但是,尽管从我的理解来看应该与上面的相同,但下面的代码没有抛出异常:
var paramList = Enumerable.Range(1, 10).ToList();
var mock = MockRepository.GeneratePartialMock<TestedClass>();
mock.Stub(/*same as above*/).WhenCalled(/*same as above*/);
foreach (var param in paramList)
mock.Expect(m => m.DoSthMultipleTimes(param));
mock.DoSthOnce(paramList);
mock.VerifyAllExpectations();
控制台输出相同,但 VerifyAllExpectations()
抛出 ExpectationViolationException。附加信息是:
TestedClass.DoSthMultipleTimes(1); Expected #1, Actual #0.
TestedClass.DoSthMultipleTimes(2); Expected #1, Actual #0.
...
TestedClass.DoSthMultipleTimes(10); Expected #1, Actual #0.
参数是正确的,但是这里到底是什么问题?
我猜是因为你的存根本身。
这段代码将注册您想要的各种期望:
foreach (var param in paramList)
mock.Expect(m => m.DoSthMultipleTimes(param));
这将设置调用 DoSthMultipleTimes(1)、DoSthMultipleTimes(2) 等的期望值。
但是您的 Mock.Stub 代码会覆盖/存根实现本身。这导致 Rhino 将执行此 override/method(而不是调用原始 class 的原始 DoSthMultipleTimes 方法)。因此,当调用 VerifyAllExpectation 时,调用了原始 class 中方法的 none 。
您可以通过删除以下内容来验证以上内容:
mock.Stub(m => m.DoSthMultipleTimes(Arg<int>.Is.Anything))
.WhenCalled(mi =>
{
// Only for debug; this method is empty in the actual test code.
Console.WriteLine("Stub called with " + mi.Arguments[0]);
});
由于您使用的是 PartialMock,如果您没有实现存根,它将调用原始方法。并且按理说,它现在将成功超越所有的期望。
(注意:使用 PartialMock 时要小心,因为如果不被存根(即:数据库调用等),它会 运行 原始方法)。
亲爱的 RhinoMocks 用户。我是 RhinoMocks 的新手,在思考问题时遇到了问题。我需要在 class 中测试两个方法,其中一个调用另一个多次。我已经分别测试了多次调用的方法,设置有些复杂,所以测试另一种方法的想法是对已经测试过的方法进行存根。这是一个最小的例子:
public class TestedClass
{
public virtual void DoSthOnce(List<int> listParam)
{
foreach (var param in listParam)
DoSthMultipleTimes(param);
}
public virtual void DoSthMultipleTimes(int intParam)
{
Console.WriteLine("param: " + intParam);
}
}
即DoSthMultipleTimes()
已经过测试。以下测试代码有效并验证是否为作为参数提供给 DoSthOnce()
.
DoSthMultipletimes()
-Method
var paramList = Enumerable.Range(1, 10).ToList();
var mock = MockRepository.GeneratePartialMock<TestedClass>();
mock.Stub(m => m.DoSthMultipleTimes(Arg<int>.Is.Anything))
.WhenCalled(mi =>
{
// Only for debug; this method is empty in the actual test code.
Console.WriteLine("Stub called with " + mi.Arguments[0]);
});
mock.DoSthOnce(paramList);
// This will not throw an exception
foreach (var param in paramList)
mock.AssertWasCalled(m => m.DoSthMultipleTimes(param));
输出符合预期:
Stub called with 1
Stub called with 2
Stub called with 3
Stub called with 4
Stub called with 5
Stub called with 6
Stub called with 7
Stub called with 8
Stub called with 9
Stub called with 10
但是,尽管从我的理解来看应该与上面的相同,但下面的代码没有抛出异常:
var paramList = Enumerable.Range(1, 10).ToList();
var mock = MockRepository.GeneratePartialMock<TestedClass>();
mock.Stub(/*same as above*/).WhenCalled(/*same as above*/);
foreach (var param in paramList)
mock.Expect(m => m.DoSthMultipleTimes(param));
mock.DoSthOnce(paramList);
mock.VerifyAllExpectations();
控制台输出相同,但 VerifyAllExpectations()
抛出 ExpectationViolationException。附加信息是:
TestedClass.DoSthMultipleTimes(1); Expected #1, Actual #0.
TestedClass.DoSthMultipleTimes(2); Expected #1, Actual #0.
...
TestedClass.DoSthMultipleTimes(10); Expected #1, Actual #0.
参数是正确的,但是这里到底是什么问题?
我猜是因为你的存根本身。
这段代码将注册您想要的各种期望:
foreach (var param in paramList)
mock.Expect(m => m.DoSthMultipleTimes(param));
这将设置调用 DoSthMultipleTimes(1)、DoSthMultipleTimes(2) 等的期望值。
但是您的 Mock.Stub 代码会覆盖/存根实现本身。这导致 Rhino 将执行此 override/method(而不是调用原始 class 的原始 DoSthMultipleTimes 方法)。因此,当调用 VerifyAllExpectation 时,调用了原始 class 中方法的 none 。
您可以通过删除以下内容来验证以上内容:
mock.Stub(m => m.DoSthMultipleTimes(Arg<int>.Is.Anything))
.WhenCalled(mi =>
{
// Only for debug; this method is empty in the actual test code.
Console.WriteLine("Stub called with " + mi.Arguments[0]);
});
由于您使用的是 PartialMock,如果您没有实现存根,它将调用原始方法。并且按理说,它现在将成功超越所有的期望。
(注意:使用 PartialMock 时要小心,因为如果不被存根(即:数据库调用等),它会 运行 原始方法)。