Mockery 的 andReturn() 执行方法,而不是模拟返回值
Posted
技术标签:
【中文标题】Mockery 的 andReturn() 执行方法,而不是模拟返回值【英文标题】:Mockery's andReturn() executing method instead of mocking return value 【发布时间】:2019-07-23 15:02:29 【问题描述】:我正在尝试测试以下方法:
/* ConfigurationService.php*/
public function checkConfigs()
$configurations = $this->getConfigurations();
return $configurations['configExample'] === '1';
考虑到getConfigurations()
方法调用了这个文件之外的其他方法,在ConfigurationRepository.php
内部,我试图只模拟它的返回并执行我想要测试的方法(checkConfigs()
):(省略了一些代码)
/* ConfigurationServiceTest.php */
$configurationRepoMock = \Mockery::mock(ConfigurationRepository::class);
$configurationRepoMock
->shouldReceive('getConfigurations')
->once()
->andReturn(['configExample' => '1']);
$configurationServiceMock = \Mockery::mock(ConfigurationService::class);
$this->app->instance('App\Services\ConfigurationService', $configurationServiceMock);
$configurationServiceInstance = new ConfigurationService($configurationRepoMock);
$response = $configService->checkConfigs();
问题是,不是返回模拟结果(['configExample' => '1']
),而是方法getConfigurations()
执行,由于其中的其他方法调用而失败,返回错误:
Mockery\Exception\BadMethodCallException:收到 Mockery_1_App_Repositories_API_ConfigurationRepository::methodInsideGetConfigurations(),但未指定预期
总结一下,andReturn()
不起作用。有什么想法吗?
【问题讨论】:
getConfigurations
看起来是ConfigurationService
的一部分,而不是您嘲笑的ConfigurationRepository
。这个方法有什么作用?
它是ConfigurationService
的一部分,但它从ConfigurationRepository
进行方法调用,然后根据这些方法返回数据
当你用这个调用替换容器中的实例时:$this->app->instance('App\Services\ConfigurationService', $configurationServiceMock);
并因此使用new
关键字来创建一个类,你不会替换任何东西。您必须使用 app(ConfigurationService::class)
从容器中解析实例才能获取模拟实例。
【参考方案1】:
刚刚找到解决办法……
$configurationServiceMock = Mockery::mock(ConfigurationService::class)->makePartial();
$configurationServiceMock
->shouldReceive('getConfigurations')
->andReturn(['configExample' => '1']);
$response = $configurationServiceMock->checkConfigs();
根据文档:http://docs.mockery.io/en/latest/cookbook/big_parent_class.html
在这些情况下,建议直接模拟方法返回,所以:
我在模拟通话中添加了makePartial()
在 Service Mock 本身中接收到模拟结果
然后andReturn()
方法按预期工作。
【讨论】:
以上是关于Mockery 的 andReturn() 执行方法,而不是模拟返回值的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Mockery - 这个测试没有执行任何断言