如何使用 Mockery 模拟嵌套对象,如 GuzzleHttp 请求
Posted
技术标签:
【中文标题】如何使用 Mockery 模拟嵌套对象,如 GuzzleHttp 请求【英文标题】:How To Use Mockery For Mocking Nested Object Like GuzzleHttp Request 【发布时间】:2020-10-05 15:38:12 【问题描述】:我在 php 中有以下代码:
$response = $this->client->request('GET', $path, $requestBody, $headers);
$isRequestSuccess = $response->getStatusCode() === "200";
if ($isRequestSuccess)
return $response->getBody()->getContents();
似乎我成功地为请求创建了一个模拟:
$mockResponse = \Mockery::mock('GuzzleHttp\Psr7\Response');
$clientMock
->shouldReceive('request')
->once()
->withAnyArgs()
->andReturn($mockResponse);
$clientMock->shouldReceive('getStatusCode')->andReturn(200);
但是,我应该如何使用 Mockery 来模拟 getStatusCode
?
它应该返回GuzzleHttp
的Psr7\Response
对象。
我知道$clientMock
返回值应该分配给一个参数,但是我应该如何模拟
$response->getStatusCode();
和
$response->getBody()->getContents()
如果我要模拟 getStatusCode
并返回 200,我会收到以下错误:
Method Mockery_4_GuzzleHttp_Psr7_Response::getStatusCode() does not exist on this mock object
【问题讨论】:
【参考方案1】:这不是$request
,而是$response
,你最好这样命名。 $request 变量包含一个响应对象,这非常令人困惑。
不管怎样,
Mockery::mock(ResponseInterface::class)->shouldReceive('getStatusCode')->andReturn(200);
更深入地看,您可能不必在意,该响应被模拟并且对测试无用,如果您正确设置模拟,您将进行测试,而不是测试您的代码。
【讨论】:
您的示例仅适用于getStatusCode
方法,但不一定适用于$response->getBody()->getContents()
。我不是在嘲笑整个函数的响应。我想模拟它在其中调用的方法,因为它是嵌套验证整个代码的一部分。同时添加错误。
我认为这是我的错。我刚刚在$mockResponse
中犯了一个错误。我没有添加makePartial
电话。
对不起,你必须模拟 StreamInterface 并让它的 getContents 方法返回预期的字符串,然后配置响应模拟的 getBody 方法以返回模拟的流。以上是关于如何使用 Mockery 模拟嵌套对象,如 GuzzleHttp 请求的主要内容,如果未能解决你的问题,请参考以下文章
这个模拟对象上不存在方法 - Laravel,Mockery