rawnato's avatar

Events are triggering even with Event::fake

Hey everyone!

I’m working on an action that triggers an event. When this event is triggered, a listener sends some data to an external API, but that’s not the main point here!

I’m writing some tests using Pest, and even when I use the Event::fake, the data is still being sent to the external API.

Any idea what might be going on?

Here’s the code for my test:

test('admin can create a package with valid data', function (): void {
  Event::fake([PackageHasBeenCreated::class]);
  $admin = User::factory()->admin()->create();
  $data = ['name' => fake()->word];

  $response = $this->actingAs($admin)->post(route('admin.packages.create'), $data);

  $response
    ->assertSessionHasNoErrors()
    ->assertRedirect(route('admin.packages.list'));

  $this->assertDatabaseHas('packages', $data);

  Event::assertDispatched(PackageHasBeenCreated::class);
});	

To trigger the event, I’m using the $dispatchesEvents property in the model, like this:

  /**
   * Events that must be fired
   */
  protected $dispatchesEvents = [
    'created' => PackageHasBeenCreated::class,
    'updated' => PackageHasBeenUpdated::class,
    'deleted' => PackageHasBeenDeleted::class,
  ];

I alreday test with Event::fake([PackageHasBeenCreated::class]); and Event::fake(PackageHasBeenCreated::class); and have the same problem!

0 likes
1 reply
LaryAI's avatar
Level 58

When using Event::fake(), it should prevent any listeners from being executed, including those that send data to external APIs. If the data is still being sent, there are a few potential reasons and solutions to consider:

  1. Check for Direct Calls: Ensure that the listener or any related code isn't being called directly in your application logic. The Event::fake() method only fakes events dispatched through Laravel's event system.

  2. Verify Listener Registration: Make sure that the listener responsible for sending data to the external API is properly registered and not being called directly. It should only be triggered by the event.

  3. Check for Other Event Dispatching: Ensure that there are no other parts of your code that might be dispatching the event outside of the model's $dispatchesEvents property.

  4. Use Event::fake() Correctly: Ensure that Event::fake() is called before any code that might dispatch the event. In your test, it seems correctly placed, but double-check the order of operations.

  5. Inspect the Listener: Review the listener to ensure it doesn't have any logic that bypasses the event system. For example, if the listener is manually invoked somewhere else in the code, it would not be affected by Event::fake().

  6. Check for Caching: If your application uses caching, ensure that the listener isn't being cached in a way that bypasses the event system.

Here's a checklist to help you debug:

  • Ensure Event::fake() is called at the beginning of your test.
  • Verify that the listener is not being called directly.
  • Check for any manual dispatching of the event.
  • Review the listener logic for any direct API calls.

If everything seems correct and the issue persists, you might want to isolate the problem by creating a minimal test case or reviewing the listener's implementation for any anomalies.

Please or to participate in this conversation.