Search code examples
laravelmockery

Laravel + Mockery InvalidCountException


I am trying to mock a class to prevent it from having to call 3rd party apis. But when setting up the mock, it doesn't seem to affect the controller action. I did try replacing the $this->postJson() by manually creating instances of the Request- and OEmbedController-classes. The create()-method is getting called, but I am receiving an error from Mockery that it isn't.

What am I doing wrong here?

Error:

Mockery\Exception\InvalidCountException : Method create() from Mockery_2_Embed_Embed should be called exactly 1 times but called 0 times.

Test:

class OEmbedTest extends TestCase
{
    public function tearDown()
    {
        Mockery::close();
    }

    /**
     * It can return an OEmbed object
     * @test
     */
    public function it_can_return_an_o_embed_object()
    {
        $url = 'https://www.youtube.com/watch?v=9hUIxyE2Ns8';

        Mockery::mock(Embed::class)
            ->shouldReceive('create')
            ->with($url)
            ->once();

        $response = $this->postJson(route('oembed', ['url' => $url]));
        $response->assertSuccessful();
    }
}

Controller:

public function __invoke(Request $request)
{
    $info = Embed::create($request->url);

    $providers = $info->getProviders();

    $oembed = $providers['oembed'];

    return response()
        ->json($oembed
            ->getBag()
            ->getAll());
}

Solution

  • I was able to solve this by using this in my test:

    protected function setUp()
    {
        parent::setUp();
    
        app()->instance(Embed::class, new FakeEmbed);
    }
    

    Then resolving it like this

    $embed = resolve(Embed::class);
    $embed = $embed->create($url);