How to use FakeItEasy to assert a method was not c

2019-07-14 18:28发布

I want to assert that nothing was dispatched, a.k.a. _dispatcher.Dispatch was not called.

interface being faked/mocked:

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

In the test body:

_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 was dispatched.

Any ideas? Am I using FakeItEasy incorrectly?

1条回答
Ridiculous、
2楼-- · 2019-07-14 19:13

@Scoobie

Is the actual type, that you call the dispatch method with, really Command? Or is it a derived type? If it's a derived type that would probably 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
{
}

The following 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 succeed, though you expected it to fail.

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

Now for your issue. I assume you want to ensure that the IDispatcher.Dispatch method is never called, no matter which type the generic argument has. You have a couple of options:

As the Dispatch method is the only one on the IDispatcher I would just write the following

A.CallTo(dispatcher).MustNotHaveHappened();

This fails when any method (or property) on the dispatcher instance is called.

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

This only fails when a call to Dispatch is made, though this usage is a refactoring killer.

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

查看更多
登录 后发表回答