文档章节

写Laravel测试代码(3)

botkenni
 botkenni
发布于 2017/09/03 22:39
字数 781
阅读 6
收藏 0

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

本文主要聊一聊写测试时如何mock第三方json api数据。

在开发时经常会调用第三方API接口,抓取json api data后进行加工处理,那如何写测试呢?如何mock数据呢?

这里举一个简单例子,AccountController::class调用Connector::class, Connector::class 会调用第三方 json api来读取数据,代码如下:

<?php

declare(strict_types=1);

namespace App\Http\Controllers;

class AccountController extends Controller
{
    /**
     * @var Connector
     */
    private $connector;

    public function index()
    {
        $connector = $this->getConnector();

        return $connector->call('accounts');
    }

    public function show(string $id)
    {
        $connector = $this->getConnector();

        return $connector->call('accounts/' . $id);
    }

    private function getConnector()
    {
        if (!$this->connector) {
            $this->connector = new Connector();
        }

        return $this->connector;
    }
}



namespace App\Http\Controllers;

use GuzzleHttp\Client;
use Illuminate\Http\Request;

class Connector
{
    public function call(string $path): array
    {
        $client = new Client();

        $response = $client->request(Request::METHOD_GET, config('app.url') . DIRECTORY_SEPARATOR . $path);

        return \GuzzleHttp\json_decode($response);
    }
}

代码很简单,但是场景却经常会遇到,关键是如何mock数据而不是发送真实http请求数据。其实很简单,只需运用Mockery库mock请求代码,从本地读取fixtures数据

首先是在tests/fixtures文件夹下准备下fixtures数据,这些json文件的数据都是真实的接口返回的数据,可以先用postman或其他工具拿到真实数据, simple_dataset 是dataset的名称,可以自定义,一般项目里都会有一个或多个dataset数据集,vendor 是第三方名称,自定义:

然后写上AccountControllerTest::class

<?php

declare(strict_types=1);

namespace Tests\Feature;

use Illuminate\Http\Request;

class AccountControllerTest extends TestCase
{
    public function testIndex()
    {
        $response = $this->call(Request::METHOD_GET, 'api/v1/accounts');

        dump($response->json());
    }

    public function testShow()
    {
        $response = $this->call(Request::METHOD_GET, 'api/v1/accounts/1');

        dump($response->json());
    }
}

然后写上路由:

Route::group(['prefix' => 'v1'], function () {
    $resources = [
        'accounts' => [\App\Http\Controllers\AccountController::class => ['index', 'show']],
    ];

    foreach ($resources as $name => $controllers) {
        foreach ($controllers as $fqcn => $actions) {
            Route::resource($name, $fqcn, ['only' => $actions]);
        }
    }
});

既然用了全局类名\App\Http\Controllers\AccountController::class,那就别忘了在app/Providers/RouteServiceProvider::mapApiRoutes 抹掉namespace

    protected function mapApiRoutes()
    {
        Route::prefix('api')
             ->middleware('api')
             ->group(base_path('routes/api.php'));
    }

最后同时在TestCase::class写上mock数据代码

<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Http\Controllers\Connector;
use Symfony\Component\Finder\SplFileInfo;
use Tests\TestCase as BaseTestCase;

class TestCase extends BaseTestCase
{
    protected const MOCK_PATH = 'tests/fixtures/simple_dataset/vendor'; // tests/fixtures/{$dataset_name}/{$vendor_name}

    public function setUp()
    {
        parent::setUp();
    
        /** @see http://docs.mockery.io/en/latest/cookbook/mocking_hard_dependencies.html?highlight=overload */
        $mock      = \Mockery::mock('overload:' . Connector::class); // Mock hard dependencies
        $mock_path = base_path(static::MOCK_PATH);

        /** @var SplFileInfo[] $files */
        $files = \File::allFiles($mock_path);

        foreach ($files as $file) {
            $api_name = substr($file->getRelativePathname(), 0, -5); // remove '.json'

            // mock Connector::call('accounts/1') && Connector::call('accounts')
            $mock->shouldReceive('call')->with($api_name)->andReturn(\GuzzleHttp\json_decode(file_get_contents($file->getRealPath()), true));
        }
    }
}

这样执行测试时就实现了读取本地的真实json数据,而不用发起真实的http请求。两个测试的response数据的确来源于本地json文件的数据:

其实,就是一句话,写测试时如果调用了第三方 json api 读取数据时,使用Mockery库去mock数据,数据来源于本地文件夹的数据,且是真实有效的数据。至于mock部分的代码想咋写就咋写。同时,上面代码里还需要注意一点是,由于Connector::class是AccountController::class 的 hard dependency,别忘了加上 overload, 代码里已经添加链接,可看官网介绍

写测试是非常重要的,需要会使用PHPUnit和Mockery这两个基本库,官网是PHP手册Mockery手册

© 著作权归作者所有

botkenni
粉丝 24
博文 568
码字总数 826456
作品 0
西城
程序员
私信 提问
加载中

评论(0)

Laravel学习笔记之PHP反射(Reflection) (上)

Laravel学习笔记之PHP反射(Reflection) (上) laravel php reflect 2.1k 次阅读 · 读完需要 80 分钟 3 说明:Laravel中经常使用PHP的反射特性来设计代码,本文主要学习PHP的反射特性,来提高...

osc_u94h44ck
2019/06/05
8
0
Laravel5.3之PHP反射(Reflection) (上)

说明:Laravel中经常使用PHP的反射特性来设计代码,本文主要学习PHP的反射特性,来提高写代码时的设计质量。PHP提供一套检测的两个工具包:和,类似于探针一样的东西来探测这些一等公民。本文...

botkenni
2016/11/07
52
0
谈谈我第一次如何为 Laravel 贡献源码

起源 办法总比困难多,所以发现问题比解决问题更难得到。 事情的起源是因为在调试一段模型事件时出现的,当时随便往数据库里插入了一段字符串 ,而不是标准的 。然后发现我的模型事件中查找不...

等月人
2018/05/28
40
0
Laravel5.3之函数处理(Function Handling)

说明:Laravel中经常使用PHP的来设计代码,本文主要学习PHP的特性,来提高写代码时的设计质量。PHP提供了一些函数处理操作的内置函数,主要有: Function Handling calluserfuncarray()/callu...

botkenni
2016/11/15
39
0
人人必备的10个 Laravel 4 扩展包

Laravel 是一个非常流行且简单易用的PHP框架,它提供了很多基础的工具(如 RESTful 路由、内置的ORM、模版等)使你能够快速的创建应用。这意味着你可以花费更少的时间来建立应用程序的模版,...

Specs
2019/09/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

2020淘宝618理想生活列车自动领喵币脚本

自动收喵币 脚本 使用教程(测试安卓手机可用) 第一步安装 auto.js 第二步录入脚本 脚本 欢迎大家在评论区反馈,方便作者修改脚本 //by 丈二auto.waitFor();var height = device.height;...

osc_7oc4d1en
39分钟前
37
1
openlayers6聚合图(附源码下载)

前言 之前写过一篇openlayers4版本的地图聚合图文章,但是由于是封装一层 js代码写的,很多初学者看起来比较有点吃力,所以本篇文章重新写一篇地图热力图文章,直接基于最新版本openlayers6...

osc_4qu6doqx
40分钟前
36
0
查找感兴趣的基因、基因组区域是否有调控元件的在线网页工具EpiRegio

前几天,Nucleic Acids Res新发了一篇文章,关于查找基因组调控元件的网页在线工具EpiRegio:https://epiregio.de/。 具体来说,该工具有以下三个功能: 1)通过给定一系列的感兴趣基因,查找...

osc_doeya1ck
41分钟前
17
0
【Gradle教程】Gradle 入门

本文为我在学习群内分享时在B站直播时的文档,直播间地址 http://live.bilibili.com/22263819 PS:问一下,Linux下有什么好用的会议软件么? 知道的朋友烦请评论告知,感谢 00.简介 Gradle 是...

osc_cyn8i2xg
42分钟前
24
0
加密后的PDF文档怎么解除密码?迅捷PDF转换器手把手教你操作!

加密后的PDF文档怎么解除密码?很多人在拿到一些珍贵的文档之后,喜欢自己先进行阅读和学习,为了避免泄露甚至会给文档进行加密,在学习完成想要进行分享的时候却发现,不知道该如何解除PDF...

dawda
43分钟前
33
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部