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() 执行方法,而不是模拟返回值的主要内容,如果未能解决你的问题,请参考以下文章

确保预期的方法是可调用的

嘲弄和method_exists

Laravel Mockery - 这个测试没有执行任何断言

Laravel Mockery 集成测试

什么是 Mockito 等价于 expect().andReturn().times()

EasyMock andReturn() 与 andStubReturn()