模拟一个改变输入值的void方法

时间:2010-04-19 11:29:34

标签: unit-testing mocking rhino-mocks rhino

如何使用参数模拟void方法并更改值参数?

我想测试一个依赖于另一个类(SomeClassB)的类(SomeClassA)。我想模仿SomeClassB。


public class SomeClassA
{
   private SomeClassB objectB;    
   private bool GetValue(int x, object y)
   {
      objectB.GetValue(x, y);      // This function takes x and change the value of y
   }
}

SomeClassB实现接口IFoo


public interface IFoo 
{
   public void GetValue(int x, SomeObject y)     // This function takes x and change the value of y
}

pulic class SomeClassB : IFoo
{
   // Table of SomeObjects 
   public void GetValue(int x, SomeObject y)
   {
       // Do some check on x
       // If above is true get y from the table of SomeObjects
   }
}

然后在我的单元测试类中,我准备了一个模仿SomeClassB.GetValue的委托类:


private delegate void GetValueDelegate(int x, SomeObject y);
private void GetValue(int x, SomeObject y)
{  // process x
   // prepare a new SomeObject obj
   SomeObject obj = new SomeObject();
   obj.field = x;
   y = obj;
}

在模拟部分我写道:


IFoo myFooObject = mocks.DynamicMock();
Expect.Call(delegate { myFooObject.Getvalue(5, null); }).Do(new GetValueDelegate(GetValue)).IgnoreArguments().Repeat.Any();

SomeObject o = new SomeObject();

myFooObject.getValue(5, o);
Assert.AreEqual(5, o.field);   // This assert fails!

我检查了几个帖子,委托似乎是模拟void方法的关键。 但是,在尝试上述操作后,它无法正常工作。你能告诉我的代表班有什么问题吗?或者模拟语句中出错了什么?


我的RhinoMocks是3.5,如果我包含IgnoreArguments(),它似乎正在删除Do部分 我刚刚找到这个页面: http://www.mail-archive.com/rhinomocks@googlegroups.com/msg00287.html

现在我已经改变了

Expect.Call(委托{myFooObject.Getvalue(5,null);})。 Do(new GetValueDelegate(GetValue))。IgnoreArguments() .Repeat.Any();

Expect.Call(委托{myFooObject.Getvalue(5,null);})。IgnoreArguments()。 Do(new GetValueDelegate(GetValue)) .Repeat.Any();

现在它完美无缺!

1 个答案:

答案 0 :(得分:4)

Kar,你使用的是旧版本的.NET还是什么?这种语法已经过时了很长时间。我也认为你做错了。犀牛模拟不是魔术 - 它不会做任何你自己不能使用额外的代码行做的事情。

例如,如果我有

public interface IMakeOrders {
  bool PlaceOrderFor(Customer c);
}

我可以用以下方式实现它:

public class TestOrderMaker : IMakeOrders {
  public bool PlaceOrderFor(Customer c) {
    c.NumberOfOrders = c.NumberOfOrder + 1;
    return true;
  }
}

var orders = MockRepository.GenerateStub<IMakeOrders>();
orders.Stub(x=>x.PlaceOrderFor(Arg<Customer>.Is.Anything)).Do(new Func<Customer, bool> c=> {
    c.NumberOfOrders = c.NumberOfOrder + 1;
    return true;  
});

阅读我为一些承包商写的this intro to RM