如何在使用Moq的测试中引发事件?

时间:2012-08-24 11:42:36

标签: unit-testing moq

以下是父类中代码实现的一部分:

handler.FooUpdateDelegate += FooUpdate(OnFooUpdate);
protected abstract void OnFooUpdate(ref IBoo boo, string s);

我有测试方法模拟处理程序:

Mock<IHandler> mHandler = mockFactory.Create<IHandler>();

此...

mHandler.Raise(x => x.FooUpdateDelegate += null, boo, s);

......没有用。它说:

  

System.ArgumentException:无法找到附加或分离方法的事件Void set_FooUpdateDelegate(FooUpdate)。

我想引发OnFooUpdate,以便触发在子类中测试的代码。

问题:如何使用Moq提升委托(不是常见的事件处理程序)?

如果我完全错过了这一点,请赐福我。

1 个答案:

答案 0 :(得分:8)

看起来你正在尝试提出代表而不是事件。是这样吗?

您的代码是否与此相符?

public delegate void FooUpdateDelegate(ref int first, string second);

public class MyClass {
    public FooUpdateDelegate FooUpdateDelegate { get; set; }
}

public class MyWrapperClass {

    public MyWrapperClass(MyClass myclass) {
        myclass.FooUpdateDelegate += HandleFooUpdate;
    }

    public string Output { get; private set; }

    private void HandleFooUpdate(ref int i, string s) {
            Output = s;
    }

}

如果是这样,那么你可以像这样直接调用myClass FooUpdateDelegate

[TestMethod]
public void MockingNonStandardDelegate() {

    var mockMyClass = new Mock<MyClass>();
    var wrapper = new MyWrapperClass(mockMyClass.Object);

    int z = 19;
    mockMyClass.Object.FooUpdateDelegate(ref z, "ABC");

    Assert.AreEqual("ABC", wrapper.Output);

}

编辑:使用界面

添加版本
public interface IMyClass
{
    FooUpdateDelegate FooUpdateDelegate { get; set; }
}    

public class MyClass : IMyClass {
    public FooUpdateDelegate FooUpdateDelegate { get; set; }
}

public class MyWrapperClass {

    public MyWrapperClass(IMyClass myclass) {
        myclass.FooUpdateDelegate += HandleFooUpdate;
    }

    public string Output { get; private set; }

    private void HandleFooUpdate(ref int i, string s) {
            Output = s;
    }

}


[TestMethod]
public void MockingNonStandardDelegate()
{

   var mockMyClass = new Mock<IMyClass>();
   // Test fails with a Null Reference exception if we do not set up
   //  the delegate property. 
   // Can also use 
   //  mockMyClass.SetupProperty(m => m.FooUpdateDelegate);

   mockMyClass.SetupAllProperties();

   var wrapper = new MyWrapperClass(mockMyClass.Object);

   int z = 19;
   mockMyClass.Object.FooUpdateDelegate(ref z, "ABC");

   Assert.AreEqual("ABC", wrapper.Output);

}