Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing with a singleton inside a validation method in Laravel

I have registered a singleton in a Service Provider (which uses a Guzzle Client in it's constructor):

public function register()
{
    $this->app->singleton(Channel::class, function ($app) {
        return new ChannelClient(new Client([
            'http_errors'=> false,
            'timeout' => 10,
            'connect_timeout' => 10
        ]));
    });
}

I have a validation method:

 public static function validateChannel($attribute, $value, $parameters, \Illuminate\Validation\Validator $validator)
    {
        $dataloader = app()->make(\App\Client\Channel::class);
        if($dataloader->search($value)){
            return true;
        }
    }

In the PHPUnit Test, how can I replace the app()->make(\App\Client\Channel::class); with a mocked Client class but still test the validation function within the test?

like image 460
Jenski Avatar asked Mar 06 '23 05:03

Jenski


1 Answers

To use a mock in your tests you can do something like this:

public function test_my_controller () {
    // Create a mock of the Random Interface
    $mock = Mockery::mock(RandomInterface::class);

    // Set our expectation for the methods that should be called
    // and what is supposed to be returned
    $mock->shouldReceive('someMethodName')->once()->andReturn('SomeNonRandomString');

    // Tell laravel to use our mock when someone tries to resolve
    // an instance of our interface
    $this->app->instance(RandomInterface::class, $mock);

    $this->post('/api/v1/do_things', ['email' => $this->email])
         ->seeInDatabase('things', [
             'email' => $this->email, 
             'random' => 'SomeNonRandomString',
         ]);
}

Be sure to checkout the mockery documentation:

http://docs.mockery.io/en/latest/reference/expectations.html

like image 53
Nitish Kumar Avatar answered Apr 25 '23 05:04

Nitish Kumar