【发布时间】:2021-03-20 16:47:07
【问题描述】:
我有以下测试:
public function it_can_find_by_id(): void
{
$oauth = factory( SuperOfficeOAuth::class )->create();
Auth::login( $oauth->user );
$content = file_get_contents( __DIR__.'/../_sample-responses/Contact/find.json' );
Http::fake( [
'superoffice.com/*' => Http::response( $content, 200, [ 'Content-Type' => 'application/json' ] ),
] );
$contact = ( new Contact )->find(3);
$this->assertIsObject( $contact );
$this->assertEquals(3, $contact->contact_id);
}
find.json 文件:
{
"ContactId": 3,
"Name": "Amadeus AS",
"Department": "AAvdeling",
"OrgNr": "",
"Number1": "AmadeusA",
"Number2": "AA10011",
"UpdatedDate": "2006-02-22T09:35:41",
"CreatedDate": "2002-07-23T16:01:34",
"Emails": [
{
"Value": "qa0@superoffice.com",
"StrippedValue": "qa0@superoffice.com",
"Description": "",
"TableRight": null,
"FieldProperties": {
}
}
]
}
class Contact extends Model
{
public function find(int $id): object
{
$this->url .= '/'.$id;
return parent::get();
}
}
// There is another class handeling tokens but isn't relevant for the example
class Model extends Client
{
public function get()
{
$this->setUrl();
$this->setHeaders();
return parent::get();
}
}
// Client Class
use GuzzleHttp\HandlerStack;
use Psr\Http\Message\StreamInterface;
use Spatie\GuzzleRateLimiterMiddleware\RateLimiterMiddleware;
use GuzzleHttp\Client as GuzzleClient;
class Client
{
public function __construct()
{
$stack = HandlerStack::create();
$stack->push(RateLimiterMiddleWare::perSecond(10));
$this->client = new GuzzleClient();
}
public function get()
{
return (object)json_decode($this->request('GET', $this->url, $this->headers)->getBody());
}
private function request(string $method, string $url, ?array $headers = null, ?array $body = null): object
{
$response = null;
try
{
$response = $this->client->request($method, $url, [
'headers' => $headers,
'body' => json_encode($body)
] );
}
catch(ClientException $exception)
{
}
return $response;
}
}
因此,在测试和调试联系人 find 方法时,parent::get() 返回 {#742} 但不是来自 find.json 文件的 json 对象。所以我的问题是如何测试/模拟响应以使其返回 json 对象?在生产中,它确实按预期返回了 json 对象。
还尝试将响应模拟如下:
$this->mock(function($mock) use($content) {
$mock->shouldReceive('request')->andReturns(new Response(200, [], $content));
});
和
$mock = Mockery::mock(Client::class);
$mock->shouldReceive('request')
->andReturn(new Response(200, [], $content));
$this->app->instance(Client::class, $mock);
和
class TestCase
{
public function createMockResponse($content, int $status = 200): Response
{
$content = utf8_encode($content);
$response = new Response($status, ['Content-Type' => 'application/json'], json_encode($content));
$mock = new MockHandler([$response]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
$this->app->instance(Client::class, $client);
return $response;
}
}
取自here。
【问题讨论】:
标签: laravel phpunit guzzle laravel-7