0
votes

I'm trying to figure out how to do a proper test about if a function is being called or not.

This function busqueda is defined within a controller AnuncioController, so I expect it being called when a user clicks on a search button which posts to anuncios/busqueda.

As far as I'm concerned, this might be done with mocks. This is what I've tried:

use \App\Http\Controllers;
class ExampleTest extends TestCase
{

   public function testBuscador()
   {
    $mock_buscador = Mockery::mock(\App\Http\Controllers\AnuncioController::class);
    $mock_buscador->shouldReceive('busqueda')->once()->andReturn(null);
    $this->visit('/')->submitForm('Buscar')->seePageIs('anuncios/busqueda');
   }

}

But the assert always fails, am I using mocks wrongly?

Error msg:

PHPUnit 4.8.21 by Sebastian Bergmann and contributors.

....E

Time: 352 ms, Memory: 23.25Mb

There was 1 error:

1) ExampleTest::testBuscador Mockery\Exception\InvalidCountException: Method busqueda() from Mockery_0_App_Http_Controllers_AnuncioController should be called exactly 1 times but called 0 times.

/var/www/html/anuncios.com/vendor/mockery/mockery/library/Mockery/CountValidator/Exact.php:37 /var/www/html/anuncios.com/vendor/mockery/mockery/library/Mockery/Expectation.php:271 /var/www/html/anuncios.com/vendor/mockery/mockery/library/Mockery/ExpectationDirector.php:120 /var/www/html/anuncios.com/vendor/mockery/mockery/library/Mockery/Container.php:297 /var/www/html/anuncios.com/vendor/mockery/mockery/library/Mockery/Container.php:282 /var/www/html/anuncios.com/vendor/mockery/mockery/library/Mockery.php:142 /var/www/html/anuncios.com/tests/ExampleTest.php:19

FAILURES! Tests: 5, Assertions: 27, Errors: 1.

Routes.php fragment:

Route::post('anuncios/busqueda', [
    'as' => 'anuncios/busqueda',
    'uses' => 'AnuncioController@busqueda',
]);

AnuncioController.php fragment:

public function busqueda(Request $request)
{...}
2
You might not need to mock the controller in this case, because if you see what is suppose to be on the page, you would know the controller is working. - whoacowboy

2 Answers

1
votes

You create the mock object $mock_buscador without actually using it. It seems like you expect any instance of App\Http\Controllers\AnuncioController to be replaced with the mock but this is not the case. You need to replace the used controller instance with the $mock_buscador mock object.

0
votes

Try using the full path to the controller.

use \App\Http\Controllers;
class ExampleTest extends TestCase
{

   public function testSearch()
   {
        $mock_search = Mockery::mock(\App\Http\Controllers\AnuncioController::class);
        // or if you aren't using php 5
        // $mock_search = Mockery::mock('\App\Http\Controllers\AnuncioController');
        $mock_search->shouldReceive('busqueda')->once()->andReturn(null); 
        $this->visit('/')->submitForm('Buscar')->seePageIs('anuncios/busqueda');

   }
}

Edit

I would use Mockery for your controller. I would use it more for Facades. I would rewrite the test to test what you want to see on the page.

use \App\Http\Controllers;
class ExampleTest extends TestCase
{

   public function testSearch()
   {
        $this->visit('/')
          ->type('expected', 'search')
          ->submitForm('Buscar')
          ->seePageIs('anuncios/busqueda')->
          ->see('expected results');

   }
}