2010-10-14 3 views
2

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

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.

Является ли это поведение предназначен? Есть ли обходные пути?

ответ

1

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

Подробнее/активность на этой StackOverflow теме: Rhino Mocks: Re-assign a new result for a method on a stub и здесь: Changing previously stubbed calls with Rhino Mocks.

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

1

Вы можете обойти его с наследованием. Если у вас есть базовый тестовый класс и некоторые подклассы тестирования, которые запускают тесты, вы можете сделать возвращаемое значение защищенным свойством базового тестового класса и установить значение в подклассах в точке до базы. Вызывается Инициализация. Так (с помощью 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(); 
    } 
0

Да, это проектируемой поведение.

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

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, вы вызываете соответствующую функцию. Дополнительным преимуществом является то, что ясно, что ваш тест использует некоторые специальные значения возвращаемых значений.

+0

Извините, я не понял ваш пример. Как это помогает решить проблему? – SiberianGuy

0

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

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

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