我在 laravel 中有一个资源 Controller 来管理我的用户。这将创建一个更新用户信息的路由,该路由接受一个带有 HTTP PUT 方法的请求。
这显示了 artisan route:list
命令输出:
+--------+--------------------------------+-----------------------------------------------------------+--------------------------------------+--------------------------------------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+--------------------------------+-----------------------------------------------------------+--------------------------------------+--------------------------------------------------------------------------------+------------+
...
| | PUT | users/{users} | users.update | App\Http\Controllers\Users\UsersController@update | auth |
它在我的网络浏览器上运行正常,但是当我尝试使用 codeception 运行测试并提交表单时,我得到一个方法不允许的异常并且测试失败。
我试着看看为什么会这样,这似乎是 codeception 提出的要求。该请求是使用 POST 而不是 PUT 方法发出的,以防止 Laravel 匹配路由。
HTML 表单不支持 PUT 方法,因此 Laravel Form
辅助类创建如下表单:
<form method="POST" action="https://myapp.dev/users/172" accept-charset="UTF-8">
<input name="_method" value="PUT" type="hidden">
...
但是,codeception 似乎没有读取_method
值。
我该如何解决这个问题?
编辑:深入查看代码,我发现测试不会覆盖请求方法,因为 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
。
最佳答案
我找到了一个解决方案,但我认为这不是写它的正确位置。
我在 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();
}
这解决了我的问题。
关于php - Laravel 和 Codeception - PUT 表单测试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34922592/