2017-07-04 51 views
1

亲爱的RhinoMocks用户在那里。我是RhinoMocks的新手,并且遇到了一些问题。我需要在一个类中测试两种方法,其中多次调用其他方法。我已经测试过多次单独调用,设置有点复杂,所以测试另一种方法的想法是对已经测试过的方法进行存根。这里是一个最小的例子:RhinoMocks VerifyAllExpectations失败多个期望在残桩方法

 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()已经过测试。以下测试代码的工作原理和验证DoSthMultipletimes()-方法是为列表中的每个元素调用的,该元素作为DoSthOnce()的参数提供。不出所料

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)); 

输出:

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(); 

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 

但是,下面的失败,从我的理解抛出一个异常,尽管它应该是与上面相同的东西,至少

控制台输出是相同的,但是VerifyAllExpectations()引发了ExpectationViolationException。附加信息是:

TestedClass.DoSthMultipleTimes(1); Expected #1, Actual #0. 
    TestedClass.DoSthMultipleTimes(2); Expected #1, Actual #0. 
    ... 
    TestedClass.DoSthMultipleTimes(10); Expected #1, Actual #0. 

参数是正确的,但究竟是什么问题?

回答

0

我猜是因为你的存根本身。

这段代码将注册所需的各种期望:

foreach (var param in paramList) 
    mock.Expect(m => m.DoSthMultipleTimes(param)); 

这将设置期望DoSthMultipleTimes(1),DoSthMultipleTimes(2)等均是被调用。

但是,您的Mock.Stub代码会覆盖/保留实现本身。这导致Rhino会执行这个覆盖/方法(而不是调用原始类的原始DoSthMultipleTimes方法)。因此,当调用VerifyAllExpectation时,原始类中的方法都不会被调用。

您可以通过删除以下验证以上:

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时要小心,因为如果不是被截断的(即:数据库调用等),它将运行原始方法)。

+0

非常感谢您的回答。我期待的是那么多。正如我试图解释的那样,运行原始非桩测试方法的设置有点复杂,并且会导致相当多的重复测试代码。这就是为什么我想首先将该方法存根的原因。这是否意味着我不能在这种特殊情况下使用Expect? – hickhack

+0

我相信你在这个特殊情况下无法使用Expect。顺便说一句,如果你已经使用AssertWasCalled进行了测试 - 你希望通过使用Expect获得更多什么? – hsoesanto

+0

没有得到,只是想明白。谢谢! – hickhack