如何使用XUnit测试INotifyCollectionChanged的CollectionChanged事件触发
问题原因
xUnit的Assert.Raises<NotifyCollectionChangedEventArgs>方法传入的handler参数是泛型的EventHandler<NotifyCollectionChangedEventArgs>委托类型,而INotifyCollectionChanged接口定义的CollectionChanged事件使用的是专用的NotifyCollectionChangedEventHandler委托,二者签名虽然参数结构一致,但属于不同的委托类型,无法隐式转换,因此出现编译错误。
解决方案1:手动适配委托(临时使用)
直接在事件绑定的位置对handler做显式委托转换即可,修改后的测试代码如下:
[Fact] public void RaiseOnAddition() { Action addition = () => Collection["new key"] = 3; Assert.Raises<NotifyCollectionChangedEventArgs>( handler => Collection.CollectionChanged += new NotifyCollectionChangedEventHandler(handler), handler => Collection.CollectionChanged -= new NotifyCollectionChangedEventHandler(handler), addition); }
解决方案2:封装专用断言方法(推荐复用)
如果项目中需要多次测试CollectionChanged事件,可以封装一个专用的断言方法,避免每次重复写委托转换代码,还可以扩展判断事件的操作类型、变更项等参数:
public static class CollectionAssert { public static void RaisesCollectionChanged<T>( T collection, Action triggerAction, NotifyCollectionChangedAction expectedAction = default) where T : INotifyCollectionChanged { NotifyCollectionChangedEventArgs receivedArgs = null; NotifyCollectionChangedEventHandler handler = (s, e) => receivedArgs = e; collection.CollectionChanged += handler; try { triggerAction(); Assert.NotNull(receivedArgs); if (expectedAction != default) { Assert.Equal(expectedAction, receivedArgs.Action); } } finally { collection.CollectionChanged -= handler; } } }
使用示例:
[Fact] public void RaiseOnAddition() { CollectionAssert.RaisesCollectionChanged( Collection, () => Collection["new key"] = 3, NotifyCollectionChangedAction.Add); }
内容的提问来源于stack exchange,提问作者Themelis
相关产品推荐
相关产品推荐

