在 laravel 测试中进行多个帖子调用时忽略帖子正文

Posted

技术标签:

【中文标题】在 laravel 测试中进行多个帖子调用时忽略帖子正文【英文标题】:Post bodies ignored when making multiple post calls in laravel test 【发布时间】:2016-09-21 22:29:58 【问题描述】:

我在 lumen5.2 中使用 laravel 组件编写我的 phpunit 测试时遇到了问题。如果我在单个测试中对我的 API 进行多次 http 调用,则我为后续调用提供的主体将被忽略,而优先提供给测试中任何 http 调用的第一个主体。使用 MakesHttpRequests 中的任何可用方法都会出现此问题,例如 post() 或 put() 或 call()。该问题与here 和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"

我发现在每次发布后调用 $this-&gt;refreshApplication() 会有所帮助,但也会破坏 DatabaseTransactions 逻辑,使数据库中充斥着污染后续测试运行的测试数据,并且还会产生类似的副作用没有解决刷新前最后一个帖子的问题。

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

【问题讨论】:

【参考方案1】:

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

public function get($uri, array $headers = [])

    $ret = parent::get($uri, $headers);
    Facade::clearResolvedInstances();
    return $ret;

我仍然不知道为什么需要这样的事情。

【讨论】:

当我对我的 api 进行 get 调用,然后使用一些参数进行 post 调用时,这些参数都不存在注入控制器操作的 Request 对象。看起来应用程序容器仍然保留我的第一个 get 调用的 Request 实例这个解决方案在 L5.5 上也不适用于我。实际上 $this-> refreshApplication() 也没有帮助。

以上是关于在 laravel 测试中进行多个帖子调用时忽略帖子正文的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 中使用 MySQL 数据库连接运行多个单元测试时出错

Laravel 忽略测试数据库连接

Vue:处理多个 API 调用的最佳实践

Laravel 仅验证已发布的项目并忽略验证数组的其余部分

Sqlite 在单元测试中忽略数据库约束

Laravel 5.8:从 javascript 但不是从浏览器调用路由时忽略中间件