Laravel API 测试 - 如何测试具有外部 API 调用的 API
Posted
技术标签:
【中文标题】Laravel API 测试 - 如何测试具有外部 API 调用的 API【英文标题】:Laravel API Test - How to test API that has external API call 【发布时间】:2016-07-19 19:33:48 【问题描述】:我的 API 代码
public function store (Request $request, $profileId)
$all = $request->all();
$token = AccessToken::with('users')->where('access_token',$request->input('access_token'))->first();
if($token && $token->users->isOwnProfile($profileId))
$rules = [
'access_token' => 'required',
'title' => 'required',
'description' => 'required',
'file_id' => 'required',
'audience_control' => 'required|in:' . join(',', PostRepository::$AUDIENCE_CONTROL),
'tags' => 'required',
];
$validator = Validator::make($all, $rules);
$error = $validator->errors()->toArray();
if ($validator->fails())
return $this->setStatusCode(401)
->setStatusMessage(trans('api.validation failed'))
->respondValidationMessage($error);
try
$response = $this->postRepository->save($request, $profileId);
if(isset($response['error']))
return $this->messageSet([
'message' => $response['error']['message'],
], $response['error']['status_code']);
return $this->setDataType('post_id')
->setStatusCode('200')
->respondWithCreatedId(trans('api.Post created'), $response->id);
catch (\Exception $e)
return $this->respondInternalError(trans('api.processing error'));
return $this->respondInternalError('404 page');
它从 save 方法调用另一个调用外部 API 的方法。
/*
* this function returns some response where it has profile_id for
* the file which in other save function is matched that the
* profile_id passed as parameter is same with file profile_id
*/
public function getFileDetails($file_id)
try
$response = json_decode((new Client())->request('GET', env('xyz','http://abc.xyz/api/v1').'/files/' . $file_id)->getBody()->getContents(), true);
catch (RequestException $e)
$response = json_decode($e->getResponse()->getBody()->getContents(), true);
return $response;
现在这是我的 API 测试函数。
public function testPostCreateChecksProfileMatchesCorrectly()
$this->json('POST', 'profiles/' . $this->getProfile()->id . '/posts' . '?access_token=' . $this->getAccessToken(), [
'title' => 'api testing title',
'description' => 'api testing description',
'audience_control' => 'public',
'tags' => [
'Animals',
'City'
],
'file_id' => '281'
])->seeJsonStructure([
'success' => [
'message',
'post_id',
'status',
],
]);
现在我的问题是如何为外部创建虚假回复 我在测试时使用 API。
我正在使用 phpUnit
和 Laravel 5.2
。
【问题讨论】:
相关:***.com/a/36281263/330267 【参考方案1】:首先,永远不要测试你不拥有的东西。外部 API 调用是您不拥有的想法。可能有一千个问题或用例可能出错,例如您的提交数据、网络错误或它们的内部错误。每一个case你都要测试一下情况,这很乏味。而是使用 moc 对象并对此有所期待。收听这个播客,http://www.fullstackradio.com/37 这将帮助您清楚地理解。
尝试将您的代码分成小块,然后分别测试每个块。您对单个测试的期望过高。将您的验证逻辑放在 FormRequest 类中,这将对您有很大帮助。
【讨论】:
我会说“永远不要测试你不拥有的东西。”是一个糟糕的建议。我总是需要一组集成测试来确保我能正确地与第 3 方交谈。这是一个小型测试套件,因为我总是为第 3 方通信引入抽象,但它确实存在。然后可以模拟抽象(但不能模拟与第 3 方的交互)。 我同意@JakubZalas。我们总是希望一切正常工作。【参考方案2】:您可以使用 PHP VCR 记录 API 请求的输出。https://github.com/php-vcr/php-vcr。
有了这个包,你就可以把它保存在 tests/fixtures 目录中。 所以在第一次之后,PHPUnit 会读取这个文件而不是做其他请求。 并且以这种方式也将添加到您的 GIT 存储库中。
首先你需要安装它:
composer require php-vcr/php-vcr
composer require php-vcr/phpunit-testlistener-vcr
第二个包将 PHPUnit 与 PHP-VCR 集成。
然后添加到你的phpunit.xml之后
<listeners>
<listener class="VCR\PHPUnit\TestListener\VCRTestListener" file="vendor/php-vcr/phpunit-testlistener-vcr/src/VCRTestListener.php" />
</listeners>
然后在您的 Laravel 应用程序的测试目录中创建名为“fixtures”的目录。
现在我们可以像这样测试:
/** @test */
public function itShouldGetVenueGpsCoordinates()
$address = "Milano, viale Abruzzi, 2";
VCR::turnOn();
VCR::insertCassette('mapquestapi');
$coordinates = $this->venueService->getVenueGpsCoordinates($address);
VCR::eject();
VCR::turnOff();
$this->assertEquals(45, number_format($coordinates['lat'], 0));
$this->assertEquals(9, number_format($coordinates['lng'], 0));
测试将创建一个夹具,在我的例子中称为“mapquestapi”,您可以将其添加到您的 GIT 存储库中。所以从第二次开始,API 将被您的测试调用,数据将从这个文件中加载,而不是发出新的请求。
如果您订阅了 Laracast,您可以在此处查看完整的视频教程。 https://laracasts.com/lessons/testing-http-requests
【讨论】:
Davide 感谢不幸的是,测试这超出了我的范围,因为我不再拥有该项目,但再次感谢?️ 希望将来对其他项目或其他人有用?以上是关于Laravel API 测试 - 如何测试具有外部 API 调用的 API的主要内容,如果未能解决你的问题,请参考以下文章
如何为调用外部 API 的 Laravel Artisan 命令编写 PHPUnit 测试,而无需物理调用该 API?
使用外部 Laravel 护照流明 api 进行 Laravel 客户端身份验证