Using Mockery with laravel, i got the error "No matching handler found for Mockery"

337 Views Asked by At

I am a beginner in testing in laravel. I tried for the first time mocking today and i am a bit lost.

English is not my native language too ^^:

Does someone know how to solve my problem ? Thank you !

Here is my class

class MessageUpdateAction
{
    public function execute(Message $message, array $data): void
    {
        $message->update($data);
    }
}

Here is the test

test('Should update message', function () {
    $this->actingAs($this->user);

    $messageToUpdate = Message::factory()->create(["user_id" => 1]);
    $newContent = 'Updated message content';

    $this->instance(
        MessageUpdateAction::class,
        Mockery::mock(MessageUpdateAction::class, function (MockInterface $mock) use ($newContent, $messageToUpdate) {
            $mock->shouldReceive("execute")->withArgs([$messageToUpdate, [
                'message' => $newContent,
            ]])->once();
        })
    );

    $response = $this->post(route("messages.update", ["message" => $messageToUpdate]), [
        'message' => $newContent,
    ]);

    $response->assertRedirect(route('messages.home'));
})->only();

And here is the error i got when executing the test

Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_2_App_Actions_Messages_MessageUpdateAction::execute(object(App\Models\Message), ['message' => 'Updated message content']). Either the method was unexpected or its arguments matched no expected argument list for this method

Objects: ( array (
  'App\\Models\\Message' => 
  array (
    'class' => 'App\\Models\\Message',
    'identity' => '#97e9324e40e3ec84f75bbd5e75982367',
    'properties' => 
    array (
      'incrementing' => true,
      'preventsLazyLoading' => false,
      'exists' => true,
      'wasRecentlyCreated' => false,
      'timestamps' => true,
      'usesUniqueIds' => false,
    ),
  ),
))

I tried using with() method instead, same result. With Mockery::any() instead of my model it works but i want to be sure that this is the good model that is passed.

1

There are 1 best solutions below

0
Adefowowe On

Try this:

    $this->instance(
        MessageUpdateAction::class,
        Mockery::mock(MessageUpdateAction::class, function (MockInterface $mock) {
            $mock->shouldReceive("execute")->with(Mockery::type('App\Models\Message')->once();
        })
    );

See these references: Similar SO Question

and Mockery Issue