Search code examples
phplaraveltestingmockery

Mockery mock and spy called 0 times on custom class in controller


I'm having difficulty with the spy and mock in Laravel 7 test when I test for MyCustomClass.

I have tried both mock before running $this->get and spy after $this->get. Both with the same error message (*below).

When running debug in the controller the $myCustomClass is still the MyCustomClass and not the mocked object.

MyCustomClass

class MyCustomClass
{
 public function execute()
 {
   return 'hello';
 }

MyController

class MyController
{
 public function show()
 {
   $myCustomClass = new MyCustomClass();

   $data = $myCustomClass->execute();

   return $data;
 }


private $mySpy;

public function testAMethod()
    {
        $spy = $this->spy(MyCustomClass::class); 

        $response = $this->get('/my/path');

        $spy->shouldHaveReceived('execute');

        $response->assertStatus(200);
    }

Error

Method execute(<Any Arguments>) from Mockery_2_App_MyCustomClass should be called
 at least 1 times but called 0 times.

Solution

  • The problem is that you are instantiating MyCustomClass yourself with the new keyword.

    In order for Laravel to be able to swap out the real class with the spy you have to use the service container.

    Something like this:

    class MyController
    {
        public function show(MyCustomClass $myCustomClass)
        {
            return $myCustomClass->execute();
        }
    }