FakeItEasy error: No calls were made to the fake object

FakeItEasy error: No calls were made to the fake object

我有一个小的 class,它有一个小方法,当事件发生时会调用它。

public class DemoUI
{
    public DemoUI(TestRunner runner)
    {
        runner.UserMessage += OnEventRunThis;
    }

    protected void OnEventRunThis(object sender, UserMessageEventArgs e)
    {
        Console.WriteLine(e.Message);
    }
}

现在在我的测试中,我创建了一个 TestRunner 类型的对象并在其上执行 Execute 方法。这引发了一个事件,该事件随后被拦截,并且 OnEventRunThis 尽职尽责地运行打印消息。但是Fake it easy报错"No calls were made to the fake object".

var _sutTestRunner = new TestRunner();
var fakeDemoUI = A.Fake<DemoUI>(x => x.WithArgumentsForConstructor(() => new DemoUI(_sutTestRunner)));

_sutTestRunner.Execute();

A.CallTo(fakeDemoUI).Where(x => x.Method.Name == "OnEventRunThis").MustHaveHappened();

方法 OnEventRunThis 被调用,因为我看到在输出 window 中打印了输出。因此,在我有限的理解中,这意味着已经对 Fake 对象进行了调用。

还是我遗漏了什么?或者还有其他办法吗?

我想我看到了两个问题:

  1. 您似乎在检查方法调用是否在您运行Execute之前发生。由于 Execute 引发触发方法调用的事件,因此尚未进行调用。
  2. OnEventRunThis 不是虚拟的,因此 FakeItEasy 无法覆盖它从而拦截调用。这就是您看到控制台消息的原因——原始代码是 运行.

像这样的东西你会过得更好:

public class DemoUI
{
    public DemoUI(TestRunner runner)
    {
        runner.UserMessage += OnEventRunThis;
    }

    protected virtual void OnEventRunThis(object sender, UserMessageEventArgs e)
    {
        Console.WriteLine(e.Message);
    }
}

…

var _sutTestRunner = new TestRunner();
var fakeDemoUI = A.Fake<DemoUI>(x =>
    x.WithArgumentsForConstructor(() => new DemoUI(_sutTestRunner)));

_sutTestRunner.Execute();

A.CallTo(fakeDemoUI)
    .Where(x => x.Method.Name == "OnEventRunThis")
    .MustHaveHappened();