Post 在 laravel 测试中进行多次 post 调用时忽略了主体

Post bodies ignored when making multiple post calls in laravel test

我在使用 laravel 组件在 lumen5.2 中编写我的 phpunit 测试时遇到了问题 运行。如果我在单个测试中对我的 API 进行多次 http 调用,我为后续调用提供的主体将被忽略,以支持提供给测试中任何 http 调用的第一个主体。使用 MakesHttpRequests 中的任何可用方法都会出现问题,例如 post() 或 put() 或 call()。该问题与 here and here 中讨论的问题相似但不完全相同,但它们的解决方案不适用或无法解决我的问题。我将其提炼为以下行为:

EchoTest.php

<?php

class EchoTest extends TestCase
{
    public function testEcho()
    {
        $this->json('POST', '/echo', ['string' => "first"]);
        $this->json('POST', '/echo', ['string' => "second"]);
        $this->json('POST', '/echo', ['string' => "third"]);
    }
}

EchoController.php

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Input;

class EchoController extends Controller
{
    public function _echo()
    {
        $input = Input::json()->all();
        var_dump($input['string']);
    }
}

routes.php

<?php

$app->post('echo', ['uses' => 'EchoController@_echo']);

输出

.string(5) "first"
string(5) "first"
string(5) "first"

我发现在每次 post 调用后调用 $this->refreshApplication() 会有所帮助,但也会破坏 DatabaseTransactions 逻辑,使数据库中散落着测试数据,从而污染后续测试运行,并且还有一对一的副作用,比如在刷新前最后 post 没有解决问题。

我很困惑我在这里做错了什么。我已经跟踪请求处理了好几层,直到我在下面的所有容器魔法中丢失了它并且在那里找不到任何明显的错误。

经过大量的反复试验,我发现在每次 http 调用后调用 Facade::clearResolvedInstances() 可以使连续的 http 调用正常工作。这似乎避免了破坏来自 refreshApplication 的数据库事务的副作用。我最终包装了所有 http 动词方法,以这种方式自动调用该方法:

public function get($uri, array $headers = [])
{
    $ret = parent::get($uri, $headers);
    Facade::clearResolvedInstances();
    return $ret;
}

我仍然不知道为什么需要这样的东西。