0

I have a small class which has a small method which gets invoked when the event is raised.

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

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

Now in my test I create an object of type TestRunner and execute Execute method on it. This raises an event which is then intercepted and the OnEventRunThis dutifully runs printing the message. But the Fake it easy reports the error that "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();

The method OnEventRunThis is getting called because I see the output getting printed in the output window. So this in my limited understanding means that the call has been made to Fake object.

Or am I missing something? Or is there any other way out to do this?

NotAgain
  • 1,927
  • 3
  • 26
  • 42

1 Answers1

3

I think I see two problems:

  1. You appear to be checking if the method call happened before you run Execute. Since Execute raises the event which triggers the method call, the call will not yet have been made.
  2. OnEventRunThis is not virtual, so FakeItEasy can't override it and thereby intercept the call. That's why you're seeing the console message—the original code is being run.

You'd be better off with something like:

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();
Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
  • make the test refactoring friendly: A.CallTo(() => fakeDemoUI.OnEventRunThis(A._, A._)).MustHaveHappend() – Urs Apr 23 '15 at 13:50
  • I was going to suggest this, @Urs, but it requires making `OnEventRunThis` public. – Blair Conrad Apr 23 '15 at 14:43
  • Making the method virtual fixed the issue. Execute indeed happens before the A.CallTo. I was tired while typing the question. – NotAgain Apr 24 '15 at 00:12