如何在 Laravel 测试中模拟类的属性
Posted
技术标签:
【中文标题】如何在 Laravel 测试中模拟类的属性【英文标题】:How to mock a property of a class in Laravel tests 【发布时间】:2019-02-08 13:48:02 【问题描述】:我在我的 laravel 5.6 应用程序中使用 ZipArchive 类来处理 zip 文件。在我的测试中,我为 ZipArchive 类创建了一个模拟,如下所示:
$this->zipArchiveMock = $this->createMock(ZipArchive::class);
我可以模拟 ZipArchive 类的方法,如下所示:
$this->zipArchiveMock->expects($this->once())
->method('open')
->will($this->returnValue(true));
我想模拟 ZipArchive 类的名为 numFiles 的属性。我试着做$this->zipArchiveMock->numFiles = 2
。但$this->zipArchiveMock->numFiles
始终为 0。如何模拟 ZipArchive 类上的属性?
谢谢
【问题讨论】:
【参考方案1】:好的,所以有 2 个选项,您可以使用 Mockery 模拟公共属性或模拟 count()
函数。
$this->zipArchiveMock->set('numFiles', 2);
(我不知道你是否使用 Mockery,但它包含在 Laravel 中,所以我假设你使用了) http://docs.mockery.io/en/latest/reference/public_properties.html
或者:
$this->zipArchiveMock->expects($this->once())
->method('count')
->will($this->returnValue(2));
编辑:
您使用的不是 Mockery,而是 phpunit。我找不到一种方法来模拟对象上的属性或使用 PHPUnit 在模拟上设置属性。相反,我建议你像这样使用 Mockery:
$this->zipArchiveMock = \Mockery::mock('ZipArchive');
$this->zipArchiveMock->set('numFiles', 2);
$this->zipArchiveMock->shouldReceive('open')
->once()
->andReturn(true);
希望这对你有用。
【讨论】:
感谢您的回复。我使用的是 PHP 7.1.21,ZipArchive 的 count() 函数仅在 7.2 中可用(参考:php.net/manual/en/ziparchive.count.php#123091)。所以我必须使用 numFiles 属性。我按照你的建议做了$this->zipArchiveMock->set('numFiles', 2);
,但后来我收到错误Call to undefined method Mock_ZipArchive_90b9991f::set()
。
我刚刚发现您正在使用 PHPUnit 模拟。而且我找不到解决您的 PHPUnit 问题的方法。 set()
方法是一种嘲弄方法。所以我更新了我的问题以进一步解释 Mockery。以上是关于如何在 Laravel 测试中模拟类的属性的主要内容,如果未能解决你的问题,请参考以下文章
如何在 PHPUnit / Laravel 中模拟 JSON 文件
在 Laravel 中运行功能测试时如何模拟服务(或服务提供者)?
如果在Laravel 5.5单元测试中隐藏密码,如何模拟用户创建