Laravel API Test - How to test API that has external API call

試著忘記壹切 提交于 2019-12-12 13:07:49

问题


My API code

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');

}

From save method it calls another method that calls an external 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;

}

Now this is my test function for 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',
        ],
    ]);
}

Now my question is how can I create a fake response for the external API when I am testing.

I am using PHPUnit & Laravel 5.2.


回答1:


First of all never test a thing that you don't own. An external API call is a think that you don't own. There may a thousand of issue or use case that could be go wrong, like your submitting data, network error, or their internal error. Each of the case you should test the situation, which is tedious. Rather use a moc object and put some expectation on that. Listen to this podcast, http://www.fullstackradio.com/37 this will help you to understand clearly.

Try to break your code into small chunk and then test each chunk separately. You are expecting too much from a single test. put your validation logic in a FormRequest class, this will help you a lot.



来源:https://stackoverflow.com/questions/36331847/laravel-api-test-how-to-test-api-that-has-external-api-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!