有没有办法对事件进行断言?

时间:2009-11-10 07:29:10

标签: c# unit-testing events

我可以测试一个事件被触发的断言吗?像这样:

[TestMethod]
public void EventFiresWhenChangingProperty()
{
    var sut = new SystemUnderTest();
    var eventRegister = new EventRegister(sut.PropertyChanged);
    sut.AnyProperty = "new value";
    Assert.EventWasFired(eventRegister);
}

当然,我可以创建一个事件处理程序,它将一些记录放入测试上下文或仅由此特定测试读取的实例变量中,但这似乎有点太多管道。我正在寻找类似上面代码的东西。

3 个答案:

答案 0 :(得分:4)

我通常将一个匿名方法挂钩为事件监听器,并在其中设置一个可测试的值,如下所示:

var sut = new SystemUnderTest();
bool eventWasRaised = false;
sut.PropertyChanged += (s, e) => eventWasRaised = true;    
sut.AnyProperty = "new value";
Assert.IsTrue(eventWasRaised);

这提供了最少量的管道。如果要添加一些清理,可以创建一个包含事件处理程序的变量:

var sut = new SystemUnderTest();
bool eventWasRaised = false;
EventHandler eh = (s, e) => eventWasRaised = true;
sut.PropertyChanged += eh;  // attach event handler
sut.AnyProperty = "new value";
Assert.IsTrue(eventWasRaised);
sut.PropertyChanged -= eh;  // detach event handler

答案 1 :(得分:0)

虽然起初似乎“不需要的管道”代码添加一个监听器实际上是一个好主意,我认为你应该这样做来测试事件。

有一些模拟框架可以让您按照自己的意愿执行,但它会为您的代码添加额外的依赖项。

保持简单 - 订阅活动。

答案 2 :(得分:0)

我同意FredrikMörk的解决方案并经常使用它。一个注意事项:最好在触发操作后插入至少20-30毫秒的Sleep,以确保有足够的时间让事件处理程序启动 - 有时候我会遇到竞争条件。