Макет пустого метода, который изменяет входное значение - PullRequest
1 голос
/ 19 апреля 2010

Как можно смоделировать метод void с параметрами и изменить параметры-значения?

Я хочу протестировать класс (SomeClassA), который зависит от другого класса (SomeClassB). Я хотел бы издеваться над 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!

Я проверил пару постов, и делегат, похоже, является ключом для насмешки над пустым методом. Однако, после попытки выше, это не работает. Не могли бы вы посоветовать, если что-то не так в моем классе делегатов? Или что-то не так в ложном утверждении?


Мой RhinoMocks 3.5, и кажется, что он отбрасывает часть Do, если я включаю IgnoreArguments () Я только что нашел эту страницу: http://www.mail-archive.com/rhinomocks@googlegroups.com/msg00287.html

Теперь я изменился

Expect.Call (делегат {myFooObject.Getvalue (5, null);}). Do (новый GetValueDelegate (GetValue)). IgnoreArguments () .Repeat.Any ();

до

Expect.Call (делегат {myFooObject.Getvalue (5, null);}). IgnoreArguments (). Do (новый GetValueDelegate (GetValue)) * .Repeat.Any ();

А теперь все отлично работает!

1 Ответ

4 голосов
/ 21 апреля 2010

Кар, ты используешь действительно старую версию .NET или что-то еще? Этот синтаксис давно устарел. Я также думаю, что вы делаете это неправильно. Rhino Mocks не волшебство - он не делает ничего, что вы не могли бы сделать самостоятельно, используя пару дополнительных строк кода.

Например, если у меня есть

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

Прочитайте это вступление к RM , которое я написал для некоторых подрядчиков.

...