Event/Listener working fine in browser but not working in test

Published 5 months ago by AR

I have an event/listener that works fine in the browser but in my test the event runs (when I dd() in its construct method) but the listener does not fire.

Here is my test:

<?php
namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use App\Events\ArticleHasNewComment;
use Illuminate\Support\Facades\Notification;
use App\Notifications\YouWereMentioned;

class MentionUsersTest extends TestCase
{
    use RefreshDatabase;

    public function setUp()
    {
        parent::setUp();

        Event::fake();
    }

    /** @test */
    public function mentioned_users_in_a_comment_are_notified()
    {
        Notification::fake();

        $john = factory('App\User')->create(['username' => 'JohnDoe']);

        $jane = factory('App\User')->create(['username' => 'JaneDoe']);

        $article = factory('App\Article')->create();

        $response = $this->actingAs($john)->json('POST',
            route('comments.store', [$article->id]), [
            'body' => '@JaneDoe take a look at this.'
            ]
        );


        Event::assertDispatched(ArticleHasNewComment::class); //passes
        Notification::assertSentTo($jane, YouWereMentioned::class); //fails
        $this->assertCount(1, $jane->fresh()->notifications); //fails
    }
}

Here is my CommentsController:

<?php

namespace App\Http\Controllers;

use Auth;
use App\Article;
use App\User;
use Illuminate\Http\Request;
use Validator;
use App\Comment;

class CommentsController extends Controller
{

    public function store(Request $request, $id)
    {

            $article = Article::find($id)->firstOrFail();

            $comment = $article->addComment([
                    'body' => $request->body,
                    'user_id' => Auth::user()->id
            ])->load('user:id,username');

        event(new ArticleHasNewComment($comment));

        return $comment;
    }

}

Here is ArticleHasNewComment:

<?php

namespace App\Events;

use Illuminate\Queue\SerializesModels;

class ArticleHasNewComment
{
    use SerializesModels;

    public $comment;

    public function __construct($comment)
    {
        //dd('test') works here and I can see it in test
        $this->comment = $comment;
    }
}

Here is NotifyMentionedUsers:

<?php

namespace App\Listeners;

use App\Events\ArticleHasNewComment;
use App\User;

class NotifyMentionedUsers
{

    public function __construct()
    {
        dd('test');//not working
    }


    public function handle(ArticleHasNewComment $event)
    {
            dd('test');//not working
        
        preg_match_all('/@([a-z0-9\._]+)/i', $event->comment->body, $matches);

        foreach ($matches[1] as $username) {
            $user = User::where('username', $username)->first();

            if ($user) {
                $user->notify(new YouWereMentioned($event->comment));
            }
        }
    }
}

here is EventServiceProvider:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    
    protected $listen = [
        'App\Events\ArticleHasNewComment' => [
            'App\Listeners\NotifyMentionedUsers',
        ],
    ];

    public function boot()
    {
        parent::boot();
    }
}

Please advice

Best Answer (As Selected By AR)
AR

I found the problem. The Event::fake(); was making it not work. I removed it and everything is fine now

AR
AR
5 months ago (27,700 XP)

I found the problem. The Event::fake(); was making it not work. I removed it and everything is fine now

Please sign in or create an account to participate in this conversation.