Поднятие событий из макета / заглушки с помощью Rhino Mocks - PullRequest
25 голосов
/ 08 ноября 2010

Как я могу вызвать событие из макета / заглушки, используя Rhino Mocks?

Я нашел некоторые ответы на этот вопрос в Интернете, но все они, похоже, используют синтаксис Record / Replay, но я использую синтаксис Arrange / Act / Assert.

Есть предложения?

Небольшой пример ...

Допустим, я использую шаблон MVVM и у меня есть класс модели:

public class MyModel
{
    private int _myValue;

    public event EventHandler ValueChanged;

    public void SetValue(int newValue)
    {
        _myValue = newValue;
        if (ValueChanged != null)
        {
            ValueChanged(this, null);
        }
    }
}

Как видите, класс имеет целочисленное значение и метод, который его устанавливает. Когда значение установлено, возникает событие ValueChanged.

Этот класс модели используется моделью представления:

public class MyViewModel
{
    private MyModel _myModel;

    public MyViewModel(MyModel myModel)
    {
        _myModel = myModel;
        _myModel.ValueChanged += ValueChangedHandler;
    }

    private void ValueChangedHandler(object sender, EventArgs e)
    {
        MyString = "Value has changed";
    }

    public string MyString { get; set; }
}

Эта модель представления прослушивает событие ValueChanged в модели и обновляет его при возникновении.

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

[TestMethod]
public void MyViewModel_ModelRaisesValueChangedEvent_MyStringIsUpdated()
{
    //Arrange.
    var modelStub = MockRepository.GenerateStub<MyModel>();
    MyViewModel viewModel = new MyViewModel(modelStub);

    //Act
    -HERE I WANT TO RAISE THE VALUE CHANGED EVENT FROM modelStub.

    //Assert.
    Assert.AreEqual("Value has changed", viewModel.MyString);
}

Обратите внимание, что это всего лишь пример, а не мой настоящий код (который более сложен). Я надеюсь, что вы можете игнорировать любые опечатки и другие мелкие ошибки.

1 Ответ

32 голосов
/ 08 ноября 2010
[TestMethod]
public void MyViewModel_ModelRaisesValueChangedEvent_MyStringIsUpdated()
{
    //Arrange.
    var modelStub = MockRepository.GenerateStub<IModel>();
    MyViewModel viewModel = new MyViewModel(modelStub);

    //Act
    modelStub.Raise(
       x => x.ValueChanged += null,
       modelStub, // sender
       EventArgs.Empty);

    //Assert.
    Assert.AreEqual("Value has changed", viewModel.MyString);
}

Редактировать: Ошибка, с которой вы сталкиваетесь, возможно, может быть решена путем изменения типа заглушки на интерфейс IModel (так работают мои собственные тесты).Я изменил его в приведенном выше примере, но вам также придется изменить объявление конструктора MyViewModel для получения типа интерфейса.

Добавление ключевого слова virtual к объявлению события также может работать.

...