FakeItEasy错误:没有对假对象进行调用

时间:2015-04-23 06:35:53

标签: c# unit-testing mocking fakeiteasy

我有一个小类,它有一个小方法,在引发事件时会被调用。

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报告的错误是"没有对假对象进行调用"。

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被调用,因为我看到输出在输出窗口中打印出来。因此,在我有限的理解中,这意味着已经对Fake对象进行了调用。

或者我错过了什么?或者还有其他方法可以做到吗?

1 个答案:

答案 0 :(得分:2)

我想我发现了两个问题:

  1. 在运行Execute之前,您似乎正在检查方法调用是否发生。由于Execute引发了触发方法调用的事件,因此尚未进行调用。
  2. OnEventRunThis不是虚拟的,因此FakeItEasy无法覆盖它,从而拦截了呼叫。这就是您查看控制台消息的原因 - 原始代码正在运行。
  3. 你最好用以下的东西:

    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();