Laravel测试| Laravel Artisan Command中的模拟对象

时间:2019-07-02 13:11:10

标签: laravel unit-testing command artisan

我想测试我的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命令测试中模拟对象?

1 个答案:

答案 0 :(得分:1)

我认为@Mesuti的意思是,如果将SFTP对象bind到服务容器,则可以在运行测试时将其与模拟对象交换出去。

您可以这样绑定它(在您的app/Providers/AppServiceProvider.php内部或新的服务提供商内部):

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

然后您可以resolve将对象放在命令处理程序中(例如$sftp = resolve('SFTP');),然后mock将其here放入测试中,如下所示:

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