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