如何在xunit中测试事件是否已触发?

5

我在类中定义了一个简单的事件,就像这样

class Request 
{
   protected virtual void OnStateChanged()
   {
      StateChanged?.Invoke(this, EventArgs.Empty);
   }

   public event EventHandler StateChanged;

   public void Approve()
   {
      OnStateChanged();
   }

}

我该如何使用xunit测试这个事件是否被触发?

我尝试了一行事件处理程序的实现。

bool eventRaised = false;
request.StateChanged += (obj, eventArgs) => eventRaised = true;
request.Approve();
Assert.True(eventRaised);

这个方法可以生效,但是有更好的方式吗?我还没有想到如何使用Assert.Raises()


1
有更好的方法吗?是什么促使您寻求更好的方法?在当前方法中缺少什么?我们可以使用不同的框架并开始神圣的测试框架战争来提出多种不同的方法;) - Fabio
完全没问题,但是这有4行代码,我在想能不能像这样写 Assert.Raises(request.StateChanged) :D 而且一开始我还以为需要创建一个新的方法,现在只有4行(但也可以只有1行 :-)。 - Muflix
1
将其包装在一个方法中,并将其用作一行代码 ;) - Fabio
1个回答

5

这是普遍建议的方法。

然而,下面的例子展示了如何使用Assert.Raises()来测试您提供的类的事件。

var request = new Request();

var evt = Assert.Raises<EventArgs>(
    h => request.StateChanged += h,
    h => request.StateChanged -= h,
    () => request.Approve());

Assert.NotNull(evt);
Assert.Equal(request, evt.Sender);
Assert.Equal(EventArgs.Empty, evt.Arguments);

然而,您的事件处理程序需要成为通用委托。

public event EventHandler<EventArgs> StateChanged;

为了使Assert.Raises按预期工作,需要使用EventHandler

1
好的,但是如果我因为实现接口(例如ICommand.CanExecuteChanged)而无法从非泛型的EventHandler更改事件类型怎么办? - Oliver Giesen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接