проверка, вызывается ли метод

Я пытаюсь понять, как правильно проверить, вызывается ли функция или нет.

Эта функция busqueda определена в контроллере AnuncioController, поэтому я ожидаю, что она будет вызываться, когда пользователь нажимает кнопку поиска, которая отправляет сообщение в anuncios/busqueda. >.

Насколько я понимаю, это можно сделать с помощью моков. Это то, что я пробовал:

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');
   }

}

Но утверждение всегда терпит неудачу, я неправильно использую макеты?

Сообщение об ошибке:

PHPUnit 4.8.21 Себастьяна Бергманна и соавторов.

....E

Время: 352 мс, Память: 23,25 Мб

Была 1 ошибка:

1) ExampleTest::testBuscador Mockery\Exception\InvalidCountException: метод busqueda() из Mockery_0_App_Http_Controllers_AnuncioController должен вызываться ровно 1 раз, но вызываться 0 раз.

/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

НЕУДАЧИ! Тестов: 5, Утверждений: 27, Ошибок: 1.

Фрагмент Routes.php:

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

Фрагмент AnuncioController.php:

public function busqueda(Request $request)
{...}

person javier_domenech    schedule 17.12.2015    source источник
comment
В этом случае вам может не понадобиться имитировать контроллер, потому что, если вы видите, что должно быть на странице, вы будете знать, что контроллер работает.   -  person whoacowboy    schedule 17.12.2015


Ответы (2)


Вы создаете фиктивный объект $mock_buscador, фактически не используя его. Похоже, вы ожидаете, что любой экземпляр App\Http\Controllers\AnuncioController будет заменен макетом, но это не так. Вам нужно заменить используемый экземпляр контроллера фиктивным объектом $mock_buscador.

person Fabian Schmengler    schedule 17.12.2015
comment
О, так я неправильно понял насмешки, не так ли? Так что в данном случае я не могу этого сделать. Как бы вы проверили, вызывается ли метод? - person javier_domenech; 18.12.2015
comment
Я думаю, что тест, который вы пытаетесь написать, не очень полезен. Вы пишете функциональный тест (нажмите кнопку => ожидайте результат). seePageIs() уже проверяет, что URL-адрес anuncio/busqueda. Дополнительное тестирование, если вызывается действие контроллера, не добавляет ценности и является слишком низким уровнем для функционального теста. Вместо этого проверьте, что происходит (или что должен видеть пользователь) - person Fabian Schmengler; 18.12.2015

Попробуйте указать полный путь к контроллеру.

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');

   }
}

Редактировать

Я бы использовал Mockery для вашего контроллера. Я бы использовал его больше для фасадов. Я бы переписал тест, чтобы проверить, что вы хотите видеть на странице.

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

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

   }
}
person whoacowboy    schedule 17.12.2015
comment
php5.6, поэтому я пробовал с $mock_search = Mockery::mock(\App\Http\Controllers\AnuncioController::class); . Все равно не получается :( - person javier_domenech; 17.12.2015
comment
busqueda имеет метод инъекции: public function busqueda(Request $request). Может быть из-за этого макет не связан с этой функцией? - person javier_domenech; 17.12.2015
comment
Method busqueda() from Mockery_0_App_Http_Controllers_AnuncioController should be called exactly 1 times but called 0 times. говорит мне, что Mockery видит ваш контроллер. Просто не звонят. Вы можете опубликовать свой маршрут к этому контроллеру. - person whoacowboy; 17.12.2015
comment
Я думал так же, но заметьте, что если я прокомментирую mock-›shouldReceive, то сработает последнее утверждение. Я обновляю пост прямо сейчас - person javier_domenech; 17.12.2015
comment
Я видел ваши правки, как видите, это мое последнее утверждение. Но меня беспокоит, почему макет не работает, кстати. - person javier_domenech; 17.12.2015
comment
Я считаю, что Mockery берет на себя объект, и вы хотите использовать его, когда вы не хотите, чтобы этот издевательский объект делал то, что он делает. Так, например, вы хотите имитировать фасад Mail, чтобы он не отправлял почту. Если бы вы успешно издевались над своим контроллером, я бы предположил, что seePageIs потерпит неудачу, потому что он никогда не будет вызван. - person whoacowboy; 17.12.2015