phplaraveltwiliotwilio-apipest

How to mock the Twilio library in Laravel


I am using the Twilio library for php/laravel to send sms message. I would like to know how I could mock it in my tests, I just want to make sure the create method is call and return a correct message

SmsController.php

$twilio = new Client('xxxxxxxxx', 'xxxxxxxxxxxxxxxxx');

$message = $twilio->messages->create(
    "whatsapp:+" . $request->input('user_phone'),
    [
        "mediaUrl" => [
            $request->input('url'),
        ],
        "from" => "whatsapp:+xxxxxxxxx",
    ]
);

return response(['message_sid' => $message->sid]);

This is the test:

use Twilio\Rest\Client;
  ....
  ....

    Http::fake();
    
        $mock = $this->partialMock(Client::class, function (MockInterface $mock) {
            $mock->shouldReceive('create')
                ->with(
                    "whatsapp:+xxxxxxxx",
                    [
                        "mediaUrl" => [
                            "https://url.com/image.jpg",
                        ],
                        "from" => "whatsapp:+xxxxxxxxx",
                    ]
                );
        });
    
        $this->postJson('/twilio/user-message')
            ->assertOk();

But I am getting this error: [HTTP 401] Unable to create record: Authentication Error - invalid username

Maybe is because it is supposed to pass in the credentiales in the constructor, but even if I do that, I should not make http request in tests. What can I do?


Solution

  • Understanding ServiceContainer is most important to use Laravel.
    It makes it easier to mock any class.

    AppServiceProvider

    use Twilio\Rest\Client;
    
    class AppServiceProvider extends ServiceProvider
    {
        public function register(): void
        {
            $this->app->bind(Client::class, function ($app) {
                return new Client('', '');
            });
        }
    

    Controller

    use Twilio\Rest\Client;
    
    $twilio = app(Client::class);
    
    $message = $twilio->messages->create()
    //
    

    Test

    use Mockery;
    use Mockery\MockInterface;
    use Twilio\Rest\Api\V2010\Account\MessageInstance;
    use Twilio\Rest\Client;
    use Twilio\Rest\Api\V2010\Account\MessageList;
    
        public function test_twilio(): void
        {
            $this->mock(Client::class, function (MockInterface $mock) {
                $message = Mockery::mock(MessageInstance::class);
                $message->sid = 0;
    
                $messages = Mockery::mock(MessageList::class);
                $messages->shouldReceive('create')->andReturn($message);
    
                $mock->messages = $messages;
            });
    
            $response = $this->get('/twilio');
    
            $response->assertOk();
        }