untymage's avatar

spying method inside of If statement

In my controller i have a if statement, i want to check if the method inside of it should have receive myMethod():

class ThreadController extends Controller
{
    public function show(Thread $thread)
    {

        if ($thread->someCheck()) {
            return $thread->myMethod();
        }

    }
}

/** @test */
public function testing_two_method_would_called()
{
    factory(Thread::class)->create();

    $spy = $this->spy(Thread::class);

    $this->getJson("api/thread/1");

    $spy->shouldHaveReceived('someCheck');
    $spy->shouldHaveReceived('myMethod');

}

Mockery\Exception\InvalidCountException : Method myMethod() from Mockery_2_Tests_Unit_Thread should be called at least 1 times but called 0 times.

I want to mock two method, But the method inside of if condition never get called the condition is always true bot mockery doesnt reach the inside of if statement

0 likes
2 replies
Sti3bas's avatar
Sti3bas
Best Answer
Level 53

@untymage it's not working, because it's not even hitting your controller method. You can verify that by adding $this->withoutExceptionHandling(); to the top of your test, you should get No query results for model [Mockery_2_App_Thread] error.

Then if you make your spy partial ($this->spy(Thread::class)->makePartial()) you will get to the other error: General error: 1 no such table: mockery_2__app__threads

You haven't specified your table name so Laravel is trying to spell it from your class name which is Mockery_2_App_Threads in this case. All you need to do is to add table property to your model class:

protected $table = 'threads';

Now you will get to another error: Received Mockery_2_App_Thread::__construct(), but no expectations were specified. This is because Laravel is trying to create a new instance of the model class for the fetched thread, but it's failing because Thread class is mocked and no expectation are specified.

You can just mock the newInstance method to just return the spy: $spy->shouldReceive('newInstance')->andReturn($spy);.

Your final test should look like this and it should pass now:

factory(Thread::class)->create();

$spy = $this->spy(Thread::class)->makePartial();
$spy->shouldReceive('newInstance')->andReturn($spy);

$this->getJson("api/thread/1");

$spy->shouldHaveReceived('someCheck');
$spy->shouldHaveReceived('myMethod');
3 likes

Please or to participate in this conversation.