如何在不同情况下测试和模拟 guzzle 响应?
How to test and mock guzzle responses in different situations?
我想测试我的 API 控制器,它使用来自其他服务的一些 guzzle 请求。
我有一个下载请求 link.
这是我的API路线
Route::group(['prefix' => '/v1'], function () {
Route::get('/exampledl', 'DownloadController@downloadChecker');
});
DownloadChecker 控制器检查用户是否是管理员或订阅者向不同域中的我的一项服务发出 guzzle 请求,如果不是,则向另一项服务发出另一个 Guzzle 请求并且对于每种情况的反应是不同的。这是控制器检查管理员角色的一部分。
$client = new Client();
try {
$response = $client->request('GET', 'https://www.example.com/api/user?u=' . $request->uid);
$json = \GuzzleHttp\json_decode($response->getBody()->getContents(), True);
// if user doesn't exist in CM
//this part has been written to avoid repeating code
if (array_key_exists('user', $json) && $json['user'] == null) {
abort(403);
}
elseif (in_array("administrator", $json['Roles'])) {
User::create([
'uid' => (int)$request->uid,
'subscription.role' => 'administrator',
]);
$client = new Client();
$response = $client->request('GET', "https://vod.example2.com/vod/2.0/videos/{$a_id}?secure_ip={$u_ip}", [
'headers' => [
'authorization' => '**********'
]
]);
$json = \GuzzleHttp\json_decode($response->getBody()->getContents(), TRUE);
if (isset($json['data']['mp4_videos'])) {
$links = [];
foreach ($json['data']['mp4_videos'] as $mp_video) {
if (stripos($mp_video, "h_144") !== false) {
$links['144p'] = $mp_video;
}
elseif (stripos($mp_video, "h_240") !== false) {
$links['240p'] = $mp_video;
}
elseif (stripos($mp_video, "h_360") !== false) {
$links['360p'] = $mp_video;
}
elseif (stripos($mp_video, "h_480") !== false) {
$links['480p'] = $mp_video;
}
elseif (stripos($mp_video, "h_720") !== false) {
$links['720p'] = $mp_video;
}
elseif (stripos($mp_video, "h_1080") !== false) {
$links['1080p'] = $mp_video;
}
}
}
我的一个测试。
public function test_user_notExist_admin()
{
$client = new Client();
$response = $client->request('GET', 'https://www.example.com/api/user_days_and_roles?u=' . request()->uid);
$json = \GuzzleHttp\json_decode($response->getBody()->getContents(), True);
$this->get('/api/v1/exampledl?uid=1&n_id=400&u_ip=104.58.1.45&dl_id=a81498a9')
->assertStatus(200)
->assertSee('links');
$this->assertDatabaseHas('users', [
'uid' => (int)request('uid'),
'subscription.role' => 'administrator',
]);
}
还有一些其他条件检查,我不确定如何模拟这些不同的情况。
我应该针对每种情况进行单元测试吗?或者有什么方法可以使测试环境 return 中的 guzzle 成为自定义响应?或者其他方式?
我得到了答案。
为了在不同情况下模拟一个函数,它只需要使用 $mock = \Mockery::mock
和 makePartial();
像这样,它让我们在不执行函数的情况下制作我们想要的每个 return:
public function test_user_notExist_admin()
{
$mock = \Mockery::mock(DownloadController::class, [
'get_download_links_from_download_server' => $this->links,
'post_details_to_log_server' => [200, "new"],
'connect' => [
"Roles" => [
"authenticated",
"subscriber"
]
, "days" => "38"
]
]
)->makePartial();
$this->get('/api/v1/exampledl?uid=1&n_id=400&u_ip=104.58.1.45&dl_id=a81498a9')
->assertStatus(200)
->assertSee('links');
$this->assertDatabaseHas('users', [
'uid' => (int)request('uid'),
'subscription.role' => 'administrator',
]);
}
我为每个 API 调用创建了一个方法,然后我在数组中用 Mockery 模拟了它们。
另一种模拟函数的方法:
$mock = Mockery::mock(DownloadController::class)->makePartial();
$mock->shouldReceive('et_download_links_from_download_server')->andReturn('123465');
$this->app->instance(DownloadController::class,$mock);
我想测试我的 API 控制器,它使用来自其他服务的一些 guzzle 请求。 我有一个下载请求 link.
这是我的API路线
Route::group(['prefix' => '/v1'], function () { Route::get('/exampledl', 'DownloadController@downloadChecker'); });
DownloadChecker 控制器检查用户是否是管理员或订阅者向不同域中的我的一项服务发出 guzzle 请求,如果不是,则向另一项服务发出另一个 Guzzle 请求并且对于每种情况的反应是不同的。这是控制器检查管理员角色的一部分。
$client = new Client(); try { $response = $client->request('GET', 'https://www.example.com/api/user?u=' . $request->uid); $json = \GuzzleHttp\json_decode($response->getBody()->getContents(), True); // if user doesn't exist in CM //this part has been written to avoid repeating code if (array_key_exists('user', $json) && $json['user'] == null) { abort(403); } elseif (in_array("administrator", $json['Roles'])) { User::create([ 'uid' => (int)$request->uid, 'subscription.role' => 'administrator', ]); $client = new Client(); $response = $client->request('GET', "https://vod.example2.com/vod/2.0/videos/{$a_id}?secure_ip={$u_ip}", [ 'headers' => [ 'authorization' => '**********' ] ]); $json = \GuzzleHttp\json_decode($response->getBody()->getContents(), TRUE); if (isset($json['data']['mp4_videos'])) { $links = []; foreach ($json['data']['mp4_videos'] as $mp_video) { if (stripos($mp_video, "h_144") !== false) { $links['144p'] = $mp_video; } elseif (stripos($mp_video, "h_240") !== false) { $links['240p'] = $mp_video; } elseif (stripos($mp_video, "h_360") !== false) { $links['360p'] = $mp_video; } elseif (stripos($mp_video, "h_480") !== false) { $links['480p'] = $mp_video; } elseif (stripos($mp_video, "h_720") !== false) { $links['720p'] = $mp_video; } elseif (stripos($mp_video, "h_1080") !== false) { $links['1080p'] = $mp_video; } } }
我的一个测试。
public function test_user_notExist_admin() { $client = new Client(); $response = $client->request('GET', 'https://www.example.com/api/user_days_and_roles?u=' . request()->uid); $json = \GuzzleHttp\json_decode($response->getBody()->getContents(), True); $this->get('/api/v1/exampledl?uid=1&n_id=400&u_ip=104.58.1.45&dl_id=a81498a9') ->assertStatus(200) ->assertSee('links'); $this->assertDatabaseHas('users', [ 'uid' => (int)request('uid'), 'subscription.role' => 'administrator', ]); }
还有一些其他条件检查,我不确定如何模拟这些不同的情况。
我应该针对每种情况进行单元测试吗?或者有什么方法可以使测试环境 return 中的 guzzle 成为自定义响应?或者其他方式?
我得到了答案。
为了在不同情况下模拟一个函数,它只需要使用 $mock = \Mockery::mock
和 makePartial();
像这样,它让我们在不执行函数的情况下制作我们想要的每个 return:
public function test_user_notExist_admin()
{
$mock = \Mockery::mock(DownloadController::class, [
'get_download_links_from_download_server' => $this->links,
'post_details_to_log_server' => [200, "new"],
'connect' => [
"Roles" => [
"authenticated",
"subscriber"
]
, "days" => "38"
]
]
)->makePartial();
$this->get('/api/v1/exampledl?uid=1&n_id=400&u_ip=104.58.1.45&dl_id=a81498a9')
->assertStatus(200)
->assertSee('links');
$this->assertDatabaseHas('users', [
'uid' => (int)request('uid'),
'subscription.role' => 'administrator',
]);
}
我为每个 API 调用创建了一个方法,然后我在数组中用 Mockery 模拟了它们。
另一种模拟函数的方法:
$mock = Mockery::mock(DownloadController::class)->makePartial();
$mock->shouldReceive('et_download_links_from_download_server')->andReturn('123465');
$this->app->instance(DownloadController::class,$mock);