单元测试在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.我的提高链接事件的方法是否正确?
你所做的一切都是正确的,只要你想让你的测试问“最后发生的事件是什么?”
您的代码按此顺序触发这两个事件
这是否“正确”取决于这些事件的目的。
如果您想测试引发的事件数量以及他们提出的顺序,可以轻松扩展现有测试:
[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