当前位置: 首页 > 知识库问答 >
问题:

Laravel和代码欺骗-测试在PUT表单上失败

哈宪
2023-03-14

我在laravel中有一个资源控制器来管理我的用户。这将创建一个更新用户信息的路由,该路由使用HTTP PUT方法接收请求。

这里显示工匠路由:list命令输出:

+--------+--------------------------------+-----------------------------------------------------------+--------------------------------------+--------------------------------------------------------------------------------+------------+
| Domain | Method                         | URI                                                       | Name                                 | Action                                                                         | Middleware |
+--------+--------------------------------+-----------------------------------------------------------+--------------------------------------+--------------------------------------------------------------------------------+------------+
...
|        | PUT                            | users/{users}                                             | users.update                         | App\Http\Controllers\Users\UsersController@update                              | auth       |

它在我的web浏览器上正常工作,但当我尝试使用codeception运行测试并提交表单时,我得到一个method not allowed异常,测试失败。

我试图了解为什么会发生这种情况,这似乎是codeception提出的请求。该请求是通过POST而不是PUT方法发出的,以防止Laravel匹配路由。

HTML表单不支持PUT方法,因此LaravelFormhelper类按如下方式创建表单:

<form method="POST" action="https://myapp.dev/users/172" accept-charset="UTF-8">
    <input name="_method" value="PUT" type="hidden">
...

然而,代码欺骗似乎没有读取_method值。

我怎样才能解决这个问题?

编辑:深入查看代码,我发现test不会重写request方法,因为request类中名为request::$httpMethodParameterOverride的常量。

/**
 * Gets the request "intended" method.
 *
 * If the X-HTTP-Method-Override header is set, and if the method is a POST,
 * then it is used to determine the "real" intended HTTP method.
 *
 * The _method request parameter can also be used to determine the HTTP method,
 * but only if enableHttpMethodParameterOverride() has been called.
 *
 * The method is always an uppercased string.
 *
 * @return string The request method
 *
 * @api
 *
 * @see getRealMethod()
 */
public function getMethod()
{
    if (null === $this->method) {
        $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));

        if ('POST' === $this->method) {
            if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
                $this->method = strtoupper($method);
            } elseif (self::$httpMethodParameterOverride) {
                $this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
            }
        }
    }

    return $this->method;
}

前面的常量值应该是true,但是,当我运行测试时,它的值是false

共有2个答案

陆洛城
2023-03-14

不能在HTML表单标记中使用PUT方法。为此,您需要使用laravel的刀片模板格式来定义表单标记。

例如{!!窗体::打开(['url'=

您还可以使用route属性来定义路由,而不是url

仇浩旷
2023-03-14

我找到了一个解决方案,但我认为这不是写它的合适地方。我在Connector\Laravel5类上添加了一行简单的代码。

public function __construct($module)
{
    $this->module = $module;
    $this->initialize();

    $components = parse_url($this->app['config']->get('app.url', 'http://localhost'));
    $host = isset($components['host']) ? $components['host'] : 'localhost';

    parent::__construct($this->app, ['HTTP_HOST' => $host]);

    // Parent constructor defaults to not following redirects
    $this->followRedirects(true);

    // Added to solve the problem of overriding the request method
    Request::enableHttpMethodParameterOverride();
}

这解决了我的问题。

 类似资料:
  • 我在使用Yii2进行Codeception时遇到了一些问题。我刚刚升级到Yii 2.0.10,一直在使用本指南 我收到错误:

  • 我正在编写一组简单的PHP函数,我只使用纯PHP7,没有框架,什么都没有。这些函数稍后将在CMS中的插件中使用,但这不是重点。我想使用Codeception为我的函数编写单元测试(为了熟悉它,我知道Codeception基本上只在这里运行PHPUnit),但我真的不知道如何以合理的方式将Codeception指向我的代码。 我的结构如下:我有,其中包含我想要测试的函数,大致如下: 我使用Compo

  • 我正在尝试使用yii2 codeception。我有一个名为Client的类,它扩展了ActiveRecord。 规则()函数: 我在tests\codeception\unit\models文件夹中创建了一个名为ClientTest的文件,该文件包含以下内容: 当我使用“codecept run unit--debug”命令运行测试时,我看到

  • 当使用带有PhpBrowser驱动程序的REST模块从代码欺骗测试发出请求时,没有数据和文件通过Silex应用程序。 更改Content-Type标头 将传递给sendPOST的文件数组更改为以下数组: 文件路径文件对象(UploadedFile) 文件数组 该测试可与Silex驱动程序一起使用,但在CI服务器上这不是一个选项。此外,我们还与邮递员进行了检查,API路由按预期工作,文件已发送,一切

  • 我正在使用Codeception框架在Laravel5应用程序中执行验收测试。我想使用一个单独的数据库进行测试,以防止真实数据库在测试中发生变化。我配置了服务器。基于Codeception文档的yml文件。但真正的数据库无论如何都会受到影响。这是我的配置文件: /协同感知。yml /测试/验收。一套yml realDB是真实的数据库,在执行验收测试后会发生更改。我尝试了不同的清理案例。一套yml:

  • 我的一个测试使用了代码欺骗,当我尝试点击一个链接时,窗口滚动到浏览器认为它应该去的地方,但是,我的站点有一个导航栏附在窗口的底部,所以当浏览器停止滚动时,底部导航覆盖了链接。 正因为如此,测试失败了。有人知道如何配置它来滚动更远一点吗?使用Codeception 1.8.5。 谢谢