单元测试在C#中引发事件

我有一些提出PropertyChanged事件的代码,我希望能够单元测试事件正在被正确提出。

引发事件的代码就像

public class MyClass : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;  

   protected void NotifyPropertyChanged(String info)
   {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
   }  

   public string MyProperty
   {
       set
       {
           if (_myProperty != value)
           {
               _myProperty = value;
               NotifyPropertyChanged("MyProperty");
           }
       }
   }
}

在我的单元测试中,使用委托,我从下面的代码中得到了一个很好的绿色测试:

[TestMethod]
public void Test_ThatMyEventIsRaised()
{
    string actual = null;
    MyClass myClass = new MyClass();

    myClass.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e)
    {
         actual = e.PropertyName;
    };

    myClass.MyProperty = "testing";
    Assert.IsNotNull(actual);
    Assert.AreEqual("MyProperty", actual);
}

但是,如果我尝试将属性的设置链接在一起,如下所示:

public string MyProperty
{
    set
    {
        if (_myProperty != value)
        {
            _myProperty = value;
            NotifyPropertyChanged("MyProperty");
            MyOtherProperty = "SomeValue";
        }
    }
}

public string MyOtherProperty
{
    set
    {
        if (_myOtherProperty != value)
        {
            _myOtherProperty = value;
            NotifyPropertyChanged("MyOtherProperty");
        }
    }
}

我对事件的测试失败 - 它捕获的事件是MyOtherProperty事件。

我很确定事件发生,我的UI反应像它一样,但我的委托只捕获最后一个事件触发。

所以我想知道:
我的测试方法是否正确?
2.我的提高链接事件的方法是否正确?


你所做的一切都是正确的,只要你想让你的测试问“最后发生的事件是什么?”

您的代码按此顺序触发这两个事件

  • Property Changed(...“My Property”...)
  • Property Changed(...“MyOtherProperty”...)
  • 这是否“正确”取决于这些事件的目的。

    如果您想测试引发的事件数量以及他们提出的顺序,可以轻松扩展现有测试:

    [TestMethod]
    public void Test_ThatMyEventIsRaised()
    {
        List<string> receivedEvents = new List<string>();
        MyClass myClass = new MyClass();
    
        myClass.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e)
        {
            receivedEvents.Add(e.PropertyName);
        };
    
        myClass.MyProperty = "testing";
        Assert.AreEqual(2, receivedEvents.Count);
        Assert.AreEqual("MyProperty", receivedEvents[0]);
        Assert.AreEqual("MyOtherProperty", receivedEvents[1]);
    }
    

    如果你正在做TDD,那么事件测试就会开始产生大量的重复代码。 我编写了一个事件监视器,为这些情况提供了更简洁的单元测试编写方法。

    var publisher = new PropertyChangedEventPublisher();
    
    Action test = () =>
    {
        publisher.X = 1;
        publisher.Y = 2;
    };
    
    var expectedSequence = new[] { "X", "Y" };
    
    EventMonitor.Assert(test, publisher, expectedSequence);
    

    有关更多详细信息,请参阅以下答案。

    使用反射单元测试在C#中引发事件

    或者我发布的一系列博客文章:

    http://gojisoft.com/blog/2010/04/22/event-sequence-unit-testing-part-1/


    这是非常古老的,甚至可能不会被阅读,但有一些很酷的新.net功能,我创建了一个INPC Tracer类,允许:

    [Test]
    public void Test_Notify_Property_Changed_Fired()
    {
        var p = new Project();
    
        var tracer = new INCPTracer();
    
        // One event
        tracer.With(p).CheckThat(() => p.Active = true).RaisedEvent(() => p.Active);
    
        // Two events in exact order
        tracer.With(p).CheckThat(() => p.Path = "test").RaisedEvent(() => p.Path).RaisedEvent(() => p.Active);
    }
    

    请参阅:https://gist.github.com/Seikilos/6224204

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

    上一篇: Unit testing that an event is raised in C#

    下一篇: C#: What are virtual events and how can they be used?