使用Rhino Mocks从模拟/存根中提升事件

haa*_*gel 26 c# events unit-testing rhino-mocks

如何使用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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,该类具有整数值和设置它的方法.设置该值时,将ValueChanged引发一个事件.

此模型类由viewmodel使用:

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; }
}
Run Code Online (Sandbox Code Playgroud)

此视图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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,这只是一个示例,而不是我的实际代码(更复杂).我希望你能忽视任何拼写错误和其他小错误.

Wim*_*nen 34

[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);
}
Run Code Online (Sandbox Code Playgroud)

编辑:您遇到的错误可能可以通过将存根类型更改为接口来解决IModel (这是我自己的测试工作的方式).我已在上面的示例中更改了它,但您还必须更改MyViewModel构造函数声明以采用接口类型.

virtual关键字添加到事件声明中也可以起作用.