【问题标题】:Moq raise event error - Parameter count mismatchMoq 引发事件错误 - 参数计数不匹配
【发布时间】:2014-02-11 15:31:14
【问题描述】:

背景

我有以下场景:

  • MailItemProxy 类,其构造函数带有 MailItem 类型的单个参数(MailItem 实际上是 Microsoft.Office.Interop.Outlook 命名空间的一部分)
  • 在 MailItemProxy 的构造函数中,注册了一个名为 PropertyChange(来自 Outlook MailItem 类)的事件:
public MailItemProxy(MailItem mailItem)
{
    this.mailItem = mailItem;
    this.mailItem.PropertyChange += this.MailItem_PropertyChange;
}

我的 MailItemProxy 类实现了 INotifyPropertyChanged,因此有自己的 PropertyChanged 事件(注意这是“PropertyChanged”而不是 Outlook MailItem 自己的“PropertyChange”时态)。

*MailItem_PropertyChange* 事件处理程序如下:

 private void MailItem_PropertyChange(string name)
 {
     if (this.PropertyChanged != null)
     {
         this.PropertyChanged(this, new PropertyChangedEventArgs(name));
     }
 }

意图

我的目的是测试 MailItem PropertyChange 事件何时触发,被测类 (MailItemProxy) 已正确订阅该事件。

我使用的测试框架是Moq

我遇到的问题是我在我尝试为 mailItemStub 引发 PropertyChange 事件的 Act 行上收到运行时错误“参数计数不匹配”。 PropertyChange 事件只接受一个由 Microsoft.Office.Interop.Outlook 命名空间中的委托 ItemEvents_10_PropertyChangeEventHandler(string Name) 定义的字符串类型参数。如果我删除了 mailItemProxy 的最后两个 Arrange 行,则 Act 行由于某种原因运行良好,但我显然需要代理,因为这是我正在测试的类。

知道为什么我会收到此错误吗?

 [TestMethod]
 public void PropertyChanged_WhenMailItemPropertyChange_EventIsCalled()
 {
     // Arrange
     bool eventDispatched = false;
     var mailItemStub = new Mock<MailItem>();
     var mailItemProxy = new MailItemProxy(mailItemStub.Object);
     mailItemProxy.PropertyChanged += (sender, args) => { eventDispatched = true; };

     // Act
     mailItemStub.Raise(x => x.PropertyChange += (name) => { });

     // Assert
     Assert.IsTrue(eventDispatched);
 }

堆栈跟踪

Test Name:  PropertyChanged_WhenMailItemPropertyChange_EventIsCalled
Test Outcome:   Failed
Test Duration:  0:00:00.2764026

Result Message: 
Test method UI.Office.UnitTests.MailItemProxyTest.PropertyChanged_WhenMailItemPropertyChange_EventIsCalled threw exception: 
System.Reflection.TargetParameterCountException: Parameter count mismatch.
Result StackTrace:  
at Moq.Mock`1.Raise(Action`1 eventExpression, Object[] args)
   at UI.Office.UnitTests.MailItemProxyTest.PropertyChanged_WhenMailItemPropertyChange_EventIsCalled()

【问题讨论】:

    标签: c# events mocking vsto moq


    【解决方案1】:

    two overloadsMock.Raise - 您需要传递EventArgsparams object[] 作为第二个args 参数。在您的情况下,您可以使用后者并传递已更改属性的string name

    例如

     mailItemStub.Raise(x => x.PropertyChange += (name) => { }, "FooBar");
    

    更多here

    【讨论】:

      【解决方案2】:

      来自有相关问题的人的更新

      我还遇到了一个问题,即在引发事件时我无法真正获得正确的参数,在我的例子中是一个(相关)参数

      这是我想在我的生产代码中实现的事件。

      private void ProcessDataSet(object sender, IMeasurementDataSet e)
      {
          ...
      }
      

      我终于找到了两种等效的语法来实现这一点(似乎两个单独的参数thismeasurementDataSet.Object 无论如何都转换为object[]):

      _dataRecorder.Raise(mock => mock.DataSetAvailable += null, new object[] {this, measurementDataSet.Object });
      _dataRecorder.Raise(mock => mock.DataSetAvailable += null, this, measurementDataSet.Object);
      
      

      我还将再次引用 Moq 的出色 Quickstart Guide - 它真的很有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-17
        • 2016-09-21
        • 2011-11-17
        • 2014-05-14
        • 2011-12-04
        • 1970-01-01
        • 2019-03-01
        • 2011-06-25
        相关资源
        最近更新 更多