Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] Add ::assertNothingDispatched() to Events::fake #35835

Merged
merged 3 commits into from Jan 11, 2021
Merged

[8.x] Add ::assertNothingDispatched() to Events::fake #35835

merged 3 commits into from Jan 11, 2021

Conversation

danilopolani
Copy link
Contributor

Add a new assertion assertNothingDispatched() to Event::fake() mock. Currently all the assertion for Events require a specific event to be provided, this will catch "any" event.

Example:

Event::fake();

// Function that should NOT dispatch any event

Event::assertNothingDispatched();

@SjorsO
Copy link
Contributor

SjorsO commented Jan 11, 2021

I think the reason you always have to provide Event::fake with specific events is because a lot of things in the framework fire events. For example: a feature test that hits a controller will always fire a RequestHandled event, which means you can never meaningfully use assertNothingDispatched in feature tests.

There might be some situations where having assertNothingDispatched is useful. But I think in most situations this assertion will fail due to default framework events.

@danilopolani
Copy link
Contributor Author

You're probably right, I had this idea because my situation was (pseudo) this:

function (bool $foo) {
  if (!$foo) {
    return;
  }

  event(new MyEvent());
}

And a simple test here would be:

Event::fake();

foo(false);
Event::assertNothingDispatched();

I know there are a lot of framework-related events (like logs and many more), but maybe this could be helpful too (?)

@mfn
Copy link
Contributor

mfn commented Jan 11, 2021

I like the concept and want to share a data point for this.

I did something similar in a private project with the Bus (made a custom BusFake for this); to "lock down" integration tests and better understand what is going on: I like to to know if I miss an event or not.

The way I handled it so far is phpunits assertPostConditions, and basically works like this:

  • check if there were any calls for assertion of e.g. queued jobs or some bus commands
  • if none is present, run the assertNoBusCommands assertions (the equivalent to assertNothingDispatched)

This requires state to track, so the pseudo code looks like this:

    protected function assertPostConditions(): void
    {
        if (!$this->assertedQueueJobs) {
            $this->assertNoJobsOnQueue();
        }

        if (!$this->assertedBusCommands) {
            $this->assertNoBusCommands();
        }

        // .. more other stuff ..

        parent::assertPostConditions();
    }

In a nutshell: this can be really useful to not "miss" anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants