How to use FakeItEasy to assert method not being called

I want to argue that nothing was sent , aka was not called . _dispatcher.Dispatch

interface

faked / mocked:

interface IDispatcher
{
    void Dispatch<T>(T command, 
                     Stuff stuff = null,
                     TimeSpan? timeout = null,
                     int? retries = null) where T : Command;
}

      

In the test:

_dispatcher = A.Fake<IDispatcher>();

// do stuff

A.CallTo(() => _dispatcher.Dispatch(A<Command>.Ignored,
                                    A<Stuff>.Ignored,
                                    A<TimeSpan?>.Ignored,
                                    A<int?>.Ignored)).MustNotHaveHappened();

      

This test passes when something is submitted .

Any ideas? Am I using FakeItEasy incorrectly?

+2


source to share


1 answer


@Scoobie

Is the actual type you are calling the dispatch method with really Command

? Or is it a derived type? If it is a derived type that will likely lead to the behavior you observed.

See the following example: var dispatcher = A.Fake ();

dispatcher.Dispatch(new Command(), new Stuff());

A.CallTo(() => dispatcher.Dispatch(A<Command>.Ignored,
                                    A<Stuff>.Ignored,
                                    A<TimeSpan?>.Ignored,
                                    A<int?>.Ignored)).MustNotHaveHappened();

      

This test will fail as expected.

But if you have something like this:

public class NewCommand : Command
{
}

      

Next test

var dispatcher = A.Fake<IDispatcher>();

dispatcher.Dispatch(new NewCommand(), new Stuff());

A.CallTo(() => dispatcher.Dispatch(A<Command>.Ignored,
                                    A<Stuff>.Ignored,
                                    A<TimeSpan?>.Ignored,
                                    A<int?>.Ignored)).MustNotHaveHappened();

      



Will be successful, although you expected it to fail.

But this is how FakeItEasy works. If you like to discuss if it should work this way, go to https://github.com/FakeItEasy/FakeItEasy and open the issue.

Now for your problem. I am assuming that you want the method to IDispatcher.Dispatch

never be called, no matter what type the generic argument has. You have several options:

Since the method Dispatch

is the only one in IDispatcher

, I'll just write the following

A.CallTo(dispatcher).MustNotHaveHappened();

      

It fails when any method (or property) of the instance is dispatcher

called.

A.CallTo(dispatcher).Where(_ => _.Method.Name == "Dispatch")
    .MustNotHaveHappened();

      

This only happens when called Dispatch

, although this usage is a refactoring killer.

I would prefer the first alternative if possible in your case.

+1


source







All Articles