megaman
megaman

Reputation: 1101

laravel mocks with multiple shouldReturn() statements

I am trying to create a laravel mock which has two shouldRecieve() statements

Something like this

$mock = $this->mock(Service::class, function (MockInterface $mock) {

$mock->shouldReceive('init')->once();

$mock->shouldReceive('process')->once();
});

ive tried several variations but no matter what it try it only mocks one of the functions

shouldrecieve can take multiple arguments as an array but if I do this there is no apparent way to set a different set of asserts/function ( once(), with(), andReturns() ect ) to each mocked function

I am instantiating Service::class with the laravel service container ie

App::make(Service::class);

How can I make this work

Upvotes: 0

Views: 1537

Answers (2)

megaman
megaman

Reputation: 1101

I have fixed this

The problem was that my Service::class has a ServiceBuilder::class and once the service builder class is instantiated a function which returns an instance of service builder runs before the functon which returns service

something like this

$serviceBuilder = App::make(ServiceBuilder::class)
$servieBuilder = $serviceBuilder->setup();
$service = $serviceBuilder->build();

To make this work This code

$mock = Mockery::mock(Service::class);

    $this->bind(Service::class, function () use ($mock) {
        $mock->shouldReceive('init')->once();
        $mock->shouldReceive('process')->once();
    
        return $mock;
    });

had to become

$builderMock = Mockery::mock(ServiceBuilder::class);
$mock = Mockery::mock(Service::class);

    $this->bind(ServiceBuilder::class, function () use (builderMock) {
        $builderMock->shouldReceive('setup')->once()->andReturn($builderMock);
        $builderMock->shouldReceive('build')->once()->andReturn($mock);
    
        return $builderMock;
    });

Upvotes: 0

matiaslauriti
matiaslauriti

Reputation: 8082

It is awesome how this awesome library do not explain that you can send a second argument to ::mock like a closure and it will do something... Awful documentation...

The documentation does not say anything, so to discard this behaviour, try doing it the normal way, instead of your code, try this one:

$mock = Mockery::mock(Service::class);

$this->bind(Service::class, function () use ($mock) {
    $mock->shouldReceive('init')->once();
    $mock->shouldReceive('process')->once();

    return $mock;
});

Upvotes: 1

Related Questions