Laravel API 测试 - 如何测试具有外部 API 调用的 API [英] Laravel API Test - How to test API that has external API call

查看:34
本文介绍了Laravel API 测试 - 如何测试具有外部 API 调用的 API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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.

解决方案

You can use PHP VCR to record the output of the API request.
https://github.com/php-vcr/php-vcr.

With this package, you will be able to save it in the tests/fixtures directory.
So after the first time, PHPUnit will read this file instead of doing other requests.
And in this way will be added also to your GIT repo.

First you need to install it using:

composer require php-vcr/php-vcr 
composer require php-vcr/phpunit-testlistener-vcr 

The second package integrates PHPUnit with PHP-VCR.

Then add to your phpunit.xml after

<listeners>
    <listener class="VCRPHPUnitTestListenerVCRTestListener" file="vendor/php-vcr/phpunit-testlistener-vcr/src/VCRTestListener.php" />
</listeners>

Then create the dir called 'fixtures' in the tests directory of your Laravel application.

Now we can test like:

/** @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));
}

The test will create then a fixture, in my case called 'mapquestapi', that you will be able to add to your GIT repo. So from the second time, the API will be called by your test, the data will be loaded from this file instead of making a new request.

If you are subscribed to Laracast you can see a complete video tutorial here. https://laracasts.com/lessons/testing-http-requests

这篇关于Laravel API 测试 - 如何测试具有外部 API 调用的 API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆