这篇文章主要讲写测试时如何mock第三方jsonapi数据。开发中经常会调用第三方API接口,抓取jsonapi数据进行处理,那么测试怎么写呢?如何模拟数据?这里举一个简单的例子,A??ccountController::class调用Connector::class,Connector::class会调用第三方jsonapi读取数据,代码如下:getConnector();返回$connector->call('accounts');}publicfunctionshow(string$id){$connector=$this->getConnector();返回$connector->call('accounts/'.$id);}privatefunctiongetConnector(){if(!$this->connector){$this->connector=newConnector();}返回$this->连接器;}}命名空间App\Http\Controllers;使用GuzzleHttp\Client;使用Illuminate\Http\Request;classConnector{publicfunctioncall(string$path):array{$client=newClient();$重新sponse=$client->request(Request::METHOD_GET,config('app.url').DIRECTORY_SEPARATOR.$path);返回\GuzzleHttp\json_decode($response);}}代码很简单,但是经常遇到的场景关键是如何模拟数据而不是发送真正的http请求数据其实很简单,只需要使用Mockery库模拟请求代码在本地读取fixtures数据即可。首先是在tests/fixtures文件夹下准备fixtures数据。这些json文件的数据是真实接口返回的数据。可以使用postman或者其他工具先获取真实数据。simple_dataset是数据集的名称,可以自定义。一般项目中会有一个或多个dataset,vendor为第三方名称,自定义:然后写AccountControllerTest::class:call(Request::METHOD_GET,'api/v1/accounts');转储($响应->json());}publicfunctiontestShow(){$response=$this->call(Request::METHOD_GET,'api/v1/accounts/1');转储($响应->json());}}然后写路由:Route::group(['prefix'=>'v1'],function(){$resources=['accounts'=>[\App\Http\Controllers\AccountController::class=>['index','show']],];foreach($resourcesas$name=>$controllers){foreach($controllersas$fqcn=>$actions){Route::resource($name,$fqcn,['只有y'=>$动作]);}}});由于使用了全局类名\App\Http\Controllers\AccountController::class,所以不要忘记擦除app/Providers/RouteServiceProvider::mapApiRoutes中的命名空间:protectedfunctionmapApiRoutes(){Route::prefix('api')->middleware('api')->group(base_path('routes/api.php'));}最后,在TestCase::classData代码中写入mock:getRelativePathname(),0,-5);//删除'.json'//mockConnector::call('accounts/1')&&Connector::call('accounts')$mock->shouldReceive('call')->with($api_name)->andReturn(\GuzzleHttp\json_decode(file_get_contents($file->getRealPath()),true));这样,测试执行数据时,读取的是本地真正的json,而不是发起真正的http请求。两次测试的响应数据确实来自于本地json文件的数据:其实一句话,如果写测试的时候调用第三方jsonapi读取数据,使用Mockery库来mock数据,数据来自本地文件夹中的数据,是真实有效的数据。至于mock部分的代码,你可以随便写。同时,上面代码中还需要注意的一点是,由于Connector::class是AccountController::class的硬依赖,所以不要忘记添加重载,代码中已经添加了链接,你可以见官网介绍。编写测试非常重要。需要用到PHPUnit和Mockery这两个基础库。官网是PHP手册和Mockery手册。
