Laravel 测试 | Laravel Artisan 命令中的模拟对象
Posted
技术标签:
【中文标题】Laravel 测试 | Laravel Artisan 命令中的模拟对象【英文标题】:Laravel Test | Mock object in Laravel Artisan Command 【发布时间】:2019-11-13 03:34:30 【问题描述】:我想测试我的 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
中运行测试结果,它来自SFTP
的原始login
方法。所以mock/stub没有生效。
所以我的问题是:如何在 Laravel Artisan 命令测试中模拟对象?
【问题讨论】:
您可以在容器中注入模拟对象。在此行之前:$this->artisan('import:foo');
你能举个例子吗?
顺便说一句:$this->app->bind(SFTP::class, $sftp);
【参考方案1】:
我认为@Mesuti 的意思是,如果您将bind 您的SFTP
对象添加到您的服务容器中,您将能够在运行测试时将其替换为模拟对象。
您可以像这样绑定它(在您的 app/Providers/AppServiceProvider.php
或新的服务提供者中):
$this->app->singleton(SFTP::class, function ($app)
return new SFTP('my.sftpenv.com');
);
然后您可以在命令的处理程序中 resolve 对象(例如 $sftp = resolve('SFTP');
),然后在您的测试中使用 mock 它,如下所示:
$this->mock(SFTP::class, function ($mock)
$mock->expects()->login('foo', 'bar')->andReturn('whatever you want it to return');
);
请注意,您正在模拟的服务应该在命令的handle
方法中解决,而不是像您在其他情况下经常做的那样在__construct
方法中解决。似乎工匠命令在测试运行之前已解决,因此如果您在命令的构造函数中解析服务,它不会解析为模拟实例。
【讨论】:
以上是关于Laravel 测试 | Laravel Artisan 命令中的模拟对象的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 从 5.5 升级到 5.6 到 5.7:未捕获 ReferenceError: axios is not defined