Laravel 测试 | Laravel Artisan Command 中的模拟对象
Laravel Test | Mock object in 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
,来自 SFTP
的原始 login
方法。所以mock/stub没有生效。
所以我的问题是:如何在 Laravel Artisan 命令测试中模拟对象?
我认为@Mesuti 的意思是,如果你 bind 你的 SFTP
对象到你的服务容器,你可以在 运行ning 时用模拟对象交换它你的测试。
您可以像这样绑定它(在您的 app/Providers/AppServiceProvider.php
或新的服务提供商内部):
$this->app->singleton(SFTP::class, function ($app) {
return new SFTP('my.sftpenv.com');
});
然后您可以 resolve the object in your command's handler (e.g. $sftp = resolve('SFTP');
) and then mock 它在您的测试中像这样:
$this->mock(SFTP::class, function ($mock) {
$mock->expects()->login('foo', 'bar')->andReturn('whatever you want it to return');
});
请注意,您正在模拟的服务应该在命令的 handle
方法中解析,而不是像您在其他情况下经常做的那样在 __construct
方法中解析。看起来 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
,来自 SFTP
的原始 login
方法。所以mock/stub没有生效。
所以我的问题是:如何在 Laravel Artisan 命令测试中模拟对象?
我认为@Mesuti 的意思是,如果你 bind 你的 SFTP
对象到你的服务容器,你可以在 运行ning 时用模拟对象交换它你的测试。
您可以像这样绑定它(在您的 app/Providers/AppServiceProvider.php
或新的服务提供商内部):
$this->app->singleton(SFTP::class, function ($app) {
return new SFTP('my.sftpenv.com');
});
然后您可以 resolve the object in your command's handler (e.g. $sftp = resolve('SFTP');
) and then mock 它在您的测试中像这样:
$this->mock(SFTP::class, function ($mock) {
$mock->expects()->login('foo', 'bar')->andReturn('whatever you want it to return');
});
请注意,您正在模拟的服务应该在命令的 handle
方法中解析,而不是像您在其他情况下经常做的那样在 __construct
方法中解析。看起来 artisan 命令在测试 运行 之前就已解析,因此如果您在命令的构造函数中解析服务,它不会解析为模拟实例。