Тест Ларавеля | Макет объекта в Laravel Artisan Command

Я хочу протестировать свою команду Laravel Artisan. Поэтому мне нужно издеваться над объектом и заглушать эти методы издевательского объекта. В моем тесте я не могу использовать реальную среду SFTP.

Это handle() моей команды:

public function handle()
{
   $sftp = new SFTP('my.sftpenv.com');
   $sftp->login('foo', 'bar');
}

Я хочу издеваться над SFTP в своем тесте:

$sftp = $this->createMock(SFTP::class);
$sftp->expects($this->any())->method('login')->with('foo', 'bar');
$this->artisan('import:foo');

Выполнение теста приводит к результату Cannot connect to ...:22, полученному из исходного метода login из SFTP. Таким образом, макет/заглушка не вступает в силу.

Итак, мой вопрос: как я могу издеваться над объектом в командном тесте Laravel Artisan?


person schellingerht    schedule 02.07.2019    source источник
comment
Вы можете ввести издевательский объект в контейнер. Перед этой строкой: $this->artisan('import:foo');   -  person Mesuti    schedule 02.07.2019
comment
Не могли бы вы привести пример?   -  person schellingerht    schedule 02.07.2019
comment
Кстати можно сделать : $this->app->bind(SFTP::class, $sftp);   -  person Mesuti    schedule 02.07.2019


Ответы (1)


Я думаю, что @Mesuti означает, что если вы привяжете свой SFTP объект в свой сервисный контейнер, вы сможете заменить его фиктивным объектом при запуске теста.

Вы можете связать его следующим образом (либо внутри вашего app/Providers/AppServiceProvider.php, либо у нового поставщика услуг):

$this->app->singleton(SFTP::class, function ($app) {
            return new SFTP('my.sftpenv.com');
        });

Затем вы можете разрешить объект в обработчике вашей команды (например, $sftp = resolve('SFTP');), а затем моделируйте его внутри вашего теста следующим образом:

$this->mock(SFTP::class, function ($mock) {
    $mock->expects()->login('foo', 'bar')->andReturn('whatever you want it to return');
});

Просто примечание для будущих читателей, что служба, над которой вы издеваетесь, должна быть разрешена в методе handle команды, а не в методе __construct, как вы часто делаете в других обстоятельствах. Похоже, что ремесленные команды разрешаются до запуска тестов, поэтому, если вы разрешаете службу в конструкторе команды, она не будет разрешаться в издевательский экземпляр.

person D Malan    schedule 02.07.2019