Rhino Mocks Restub функция

Иногда я заглушаю зависимости в настройках тестового класса, а затем хочу перезапустить некоторые из них в конкретном тесте. Но насмешки Rhino запоминают только первое значение заглушки, и это немного неудобно.

someStub.Stub(x => x.SomeMethod(1)).Return(100);
var value1 = someStub.SomeMethod(1);
someStub.Stub(x => x.SomeMethod(1)).Return(200);
var value2 = someStub.SomeMethod(1);

значение 2 будет равно 100.

Это продуманное поведение? Есть ли обходные пути?

4 ответа

Решение

Я столкнулся с необходимостью сделать это сам. Я работал над этим с помощью WhenCalled функция, в которой вы передаете действие, которое будет выполнено при вызове функции. Это даст вам больше гибкости в том, что вы можете вернуть в разные моменты.

Больше информации / активности в этом потоке stackru: Moh Rhino: переназначить новый результат для метода на заглушке, а здесь: Изменение ранее обработанных вызовов с помощью Rhino Mocks.

Я знаю, что это старо, но надеюсь, что это поможет кому-то еще.

Вы можете обойти это с наследованием. Если у вас есть базовый тестовый класс и несколько тестовых подклассов, которые запускают тесты, вы можете сделать возвращаемое значение защищенным свойством базового тестового класса и установить значение в подклассах на уровне перед базовым. Инициализация называется. Таким образом (используя MSTEST) вы можете получить:

в вашем базовом классе:

protected int ReturnVal{get; set;}

public void Init()
{
someStub = MockRepository.GenerateMock<ISomeStub>();
someStub.Stub(x => x.SomeMethod(1)).Return(ReturnVal);
}

в вашем подклассе:

  [TestInitialize]
    public override Init()
    {
    ReturnVal = 200;
    base.Init();
    }

Да, это спроектированное поведение.

Обходной путь, который я использую большую часть времени, заключается в создании вспомогательного метода, который установит заглушку для вас, т.е.

private X MockX()
{
  return MockX(100);  
}

private X MockX(int returnValue)
{
  var x = MockRepository.GenerateStub<X>();
  someStub.Stub(x => x.SomeMethod(1)).Return(returnValue);
  return x;
}

и затем в своем тесте вместо использования макета, созданного в SetUp, вы вызываете соответствующую функцию. Дополнительным преимуществом является то, что ясно, что ваш тест использует некоторые специальные значения возвращаемых значений.

Вы можете использовать mocks вместо заглушек, чтобы записать такой сценарий:

[Test]
public void Mytest()
{
   var mocks = new MockRepository();
   var someMock = mocks.DynamicMock<IFoo>();
   someMock.SomeMethod(1);
   LastCall.Return(100);
   someMock.SomeMethod(1);
   LastCall.Return(200);
   mock.Replay(); // stop recording, go to replay mode

   // actual test, normally you would test something which uses the mock here
   int firstResult = someMock.SomeMethod(1);
   int secondResult = someMock.SomeMethod(2);

   // verify the expectations that were set up earlier 
   // (will fail if SomeMethod is not called as in the recorded scenario)
   someMock.VerifyAll();
}

Насмешки в носорогах Насмешки сложнее настроить, чем заглушки. Они также смешивают определение поведения с созданием утверждений (фаза записи выполняет обе функции) и полагаются на порядок вызовов методов. Это делает для хрупких испытаний; придерживайтесь окурков, если вам действительно не нужны насмешки.

Другие вопросы по тегам