C#和Moq,在抽象类模拟的接口中声明事件

我正在编写单元测试,并在尝试从抽象类模拟中提出事件时收到异常。 以下是示例代码:

    public abstract class AbstractBase : EntityObject
    {}

    [TestMethod]
    public void MyTest()
    {

        var mock = new Mock<AbstractBase>();
        var notificationMock = entityMock.As<INotifyPropertyChanged>();

        var propertyChangedMapper = new PropertyChangedMapper();

        bool eventReceived = false;
        propertyChangedMapper.MyPropertyChanged +=
            (sender, eventArgs) =>
                {
                    eventReceived = true;
                };

        propertyChangedMapper.Subscribe((AbstractBase)notificationMock.Object);

        Assert.IsFalse(eventReceived);

        notificationMock.Raise(e=>e.PropertyChanged += null, 
                                   new PropertyChangedEventArgs("Property1"));

        Assert.IsTrue(eventReceived);
  }

很明显,我可以在INotifyPropertyChanged上使用模拟和事件上升很好,但在PropertyChangedMapper我需要将发件人强制转换为AbstractBase ,如果使用Mock<INotifyPropertyChanged>

编辑 :根据建议使用Mock.As<>()似乎是正确的路要走,上面唯一的问题是,从notificationMock升起的事件与该对象的原始模拟无关。 码:

        notificationMock.Object.PropertyChanged += (s, e) =>
        {
            var result = "this one is fired as it should";
        };

        mock.Object.PropertyChanged += (s, e) =>
        {
            var result = "this one is not called but is actually what I need";
        }; 

        notificationMock.Raise(e => e.PropertyChanged += null, 
                 new PropertyChangedEventArgs("Property1"));

如果你的模拟是多模拟的,你也许可以进行想要的演员阵容。 由于Moq mock通过泛型参数绑定到单个类型,所以您必须明确逐步向模拟中添加更多接口或超类,然后在测试中使用最终产品。 下面是一个简单的例子。

var baseMock = new Mock<AbstractBase>();
var inpcMock = baseMock.As<INotifyPropertyChanged>();

// ...setup event...

propertyChangedMapper.Subscribe(inpcMock.Object);

// ... assertions ...

鉴于你这样做的方式,没有实现该事件。 接口本身只是说“我有一个PropertyChanged事件”的合同。 如果你想提出这个事件,你必须提供一个处理程序,即使它没有做任何事情。 在你的模拟类中实现PropertyChanged事件来引发事件。

更新:

试试这个代码为您的AbstractBase:

public abstract class AbstractBase : INotifyPropertyChanged
{
     public virtual event PropertyChangedEventHandler PropertyChanged;
     private void NotifyPropertyChanged(String info)
     {
         if (PropertyChanged != null)
         {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
         }
     }
}

您的PropertyChanged事件是否被声明为virtual事件?

public abstract class AbstractBase : INotifyPropertyChanged
{
   public virtual event PropertyChangedEventHandler PropertyChanged;
}

(另见:Jon Skeet关于虚拟事件。)

链接地址: http://www.djcxy.com/p/9151.html

上一篇: C# and Moq, raise event declared in interface from abstract class mock

下一篇: What does sys.maxunicode mean?