无法向Laravel端点发出HTTP请求

时间:2018-10-10 08:57:01

标签: php laravel

在我的一个测试中尝试发出HTTP请求时,我遇到了一个非常奇怪的问题。我的api.php路由文件如下所示:

$router->group(['prefix' => '/v1', 'middleware' => ['auth:api']], 
    function (\Illuminate\Routing\Router $router) {
        $router->apiResource('/contacts', 'ContactsController');

        $router->group(['prefix' => '/contacts'], 
            function (\Illuminate\Routing\Router $router) {
                $router->apiResource('/groups', 'Contacts\\GroupsController');
        });
});

正在运行php artisan route:list,表示已注册以下路线

+------------+------------------------+--------------+------------------------------------------------------+----------------+
|   Method   |           URI          |      Name    |                        Action                        |   Middleware   |
+------------+------------------------+--------------+------------------------------------------------------+----------------+
| GET|HEAD   | api/v1/contacts/groups | groups.index | App\Http\Controllers\Contacts\GroupsController@index |  api auth:api  |
+------------+------------------------+--------------+------------------------------------------------------+----------------+

但是,当我运行测试时,会收到404响应。测试如下:

public function testICanGetAllOfTheGroups()
{
    factory(Group::class)->times(3)->create();

    $this->json('GET', '/api/v1/contacts/groups')
            ->assertStatus(200)->assertJsonCount(3);
}

我也尝试过运行php artisan route:clearphp artisan cache:clear,但是并没有改变。

为了进行身份验证,我创建了以下正在使用的特征。

trait Authenticated
{
    /** @var \App\Models\User */
    protected $user;

    public function setUp()
    {
        parent::setUp();

        $this->user = factory(User::class)->create();
        Passport::actingAs($this->user);
    }
}

3 个答案:

答案 0 :(得分:0)

这是一条经过身份验证的路由。 要在测试中访问此路由,您需要使用

$this->actingAs(User $user); 

方法。

参考:Laravel Docs

您的代码应如下所示:

public function testICanGetAllOfTheGroups()
{
    factory(Group::class)->times(3)->create();
    $user = factory(User::class)->create();  // Create user for authentication
    this->actingAs($user)                  // Pass user to the request
        ->json('GET', '/api/v1/contacts/groups')->assertStatus(200)->assertJsonCount(3);
}

希望这对您有所帮助。

答案 1 :(得分:0)

我似乎已经知道了。如果我重新安排

的路线
$router->group(['prefix' => '/v1', 'middleware' => ['auth:api']], function (\Illuminate\Routing\Router $router) {
    $router->apiResource('/contacts', 'ContactsController');

    $router->group(['prefix' => '/contacts'], function (\Illuminate\Routing\Router $router) {
        $router->apiResource('/groups', 'Contacts\\GroupsController');
    });
});

$router->group(['prefix' => '/v1', 'middleware' => ['auth:api']], function (\Illuminate\Routing\Router $router) {
    $router->group(['prefix' => '/contacts'], function (\Illuminate\Routing\Router $router) {
        $router->apiResource('/groups', 'Contacts\\GroupsController');
    });

    $router->apiResource('/contacts', 'ContactsController');
});

然后工作。我怀疑这是Laravel如何注册路由的错误,因为POSTPUT请求仍然可以正常工作。

我在GitHub-https://github.com/laravel/framework/issues/26038

上提出了这个错误

更新

我现在已经确定了问题。基本上apiResource会将端点之一转换为:

/contacts/{contact}

从其中一条路由开始,依次是contacts/groups。但是,为了使Laravel与contacts/groups匹配,它必须在/contacts/{contact}之前,因为它是通配符。我不确定这是否是故意行为,但目前只有另一种方法可以解决此问题。

答案 2 :(得分:0)

为什么不将两条路线都放在contacts组中?

$router->group(['prefix' => '/v1', 'middleware' => ['auth:api']], function (\Illuminate\Routing\Router $router) {
    $router->group(['prefix' => '/contacts'], function (\Illuminate\Routing\Router $router) {
        $router->apiResource('/', 'ContactsController');
        $router->apiResource('/groups', 'Contacts\\GroupsController');
    });
});