要模拟的代码如下所示:
class Foo : IBar
{
public virtual event EventHandler FooEventHandler;
void FooMethod()
{
// blah, blah, blah...
}
void IBar.BarMethod()
{
this.FooEventHandler?.Invoke(this, new EventArgs());
}
}
interface IBar
{
void BarMethod();
}
我想模拟Foo和它的IBar实现,这样我就可以把它交给被测试的对象并断言。需求告诉我不允许将事件处理程序放在IBar接口上,所以这个链接背后的解释似乎不适合我。
编辑:
我试着在这里添加清晰,但我不确定它是否有效。
使用Mock.As<T>()
方法允许创建遵循多个接口的模拟。由于要求事件签名不能存在于IBar
接口上,我模拟了具体的Foo
类,然后使用.As<IBar>()
将IBar
分配给模拟。.As<IBar>
的返回允许我设置.BarMethod()
,以便在IBar
的模拟上使用接受lambda表达式的.Raises(...)
方法引发事件。在这个表达式中,使用.As<Foo>()
允许在设置IBar
的上下文中访问正在模拟的具体的虚拟事件处理程序。
var foo = new Mock<Foo>();
foo.As<IBar>()
.Setup(bar => bar.BarMethod())
.Raises(bar => bar.As<Foo>().FooEventHandler += null, new EventArgs());