模拟GuzzleHttp \ Client测试Lumen路线

时间:2018-04-10 15:25:13

标签: php laravel unit-testing lumen guzzlehttp

我有一个简单的Lumen应用程序使用以下两个文件,在请求根路由/时,它会使用GuzzleHttp\Client请求获取URL:

routes/web.php

<?php

$router->get('/', ['uses' => 'MyController@index', 'as' => 'index']);

app/Http/Controllers/MyController

<?php

namespace App\Http\Controllers;

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

class MyController extends Controller {
    protected $client;

    public function __construct() {
        $this->client = new Client();
    }

    public function index( Request $request ) {
        $response = $this->client->request( 'get', 'https://www.google.com/' );
        return Response()->json( [ 'status' => $response->getStatusCode() ] );
    }
}

但是,我想编写一个$response->getStatusCode()将返回444的测试,因此我编写了以下测试,尝试在getStatusCode()中模拟GuzzleHttp\Client方法:< / p>

<?php

use GuzzleHttp\Client;

class MyTest extends TestCase {
    protected $instance;

    public function testMyRoute() {
        $client = Mockery::mock( Client::class )
                         ->shouldReceive( 'getStatusCode' )
                         ->once()
                         ->andReturn( 444 );
        $this->app->instance( Client::class, $client );

        $this->json( 'get', '/' )->seeJson( [ 'status' => 444 ] );
    }

    public function tearDown() {
        parent::tearDown();
        Mockery::close();
    }
}

但是phpunit运行失败:

~/experiment/lumen-test/testing » phpunit                                                                                                                                 
PHPUnit 5.7.27 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 868 ms, Memory: 14.00MB

There was 1 failure:

1) MyTest::testMyRoute
Unable to find JSON fragment ["status":444] within [{"status":200}].
Failed asserting that false is true.

~/experiment/lumen-test/testing/vendor/laravel/lumen-framework/src/Testing/Concerns/MakesHttpRequests.php:288
~/experiment/lumen-test/testing/vendor/laravel/lumen-framework/src/Testing/Concerns/MakesHttpRequests.php:213
~/experiment/lumen-test/testing/tests/MyTest.php:15

FAILURES!
Tests: 1, Assertions: 2, Failures: 1.

这表明嘲弄没有任何效果。我在这里缺少什么?

编辑-1

根据@ sam的评论Mocking GuzzleHttp\Client for testing Lumen route修改MyController构造函数后,我将测试修改为如下:

use GuzzleHttp\Psr7\Response;

-

public function testMyRoute() {
    $response = new Response(444);
    $client = Mockery::mock( Client::class )
                     ->makePartial()
                     ->shouldReceive( 'request' )
                     ->once()
                     ->andReturn( $response );
    $this->app->instance( Client::class, $client );

    $this->json( 'get', '/' )->seeJson( [ 'status' => 444 ] );
}

1 个答案:

答案 0 :(得分:1)

您正在构造函数中实例化Client,这意味着它没有从容器中解析出来。您的控制器应该接受Client作为构造函数中的参数,该参数将由Laravel从容器中解析出来。

public function __construct(Client $client = null) {
    $this->client = $client ?: new Client;
}

如果尚未提供新Client,则只会创建新的var dict = {}; var list = ['0', '0', '0', '1'];

https://laravel.com/docs/5.6/container#resolving

  

自动注入

     

或者,重要的是,您可以“类型提示”容器解析的类的构造函数中的依赖项,包括控制器,事件侦听器,队列作业,中间件等。实际上,这就是容器应该解析大多数对象的方式。