在 Laravel 5 中,为什么在 phpunit 测试期间调用 Request::root() 不同?
In Laravel 5, why is Request::root() different when called during phpunit test?
我定义了一个测试用户创建的测试。控制器设置为在出错时重定向回同一页面(通过生成的 App\Http\Requests\Request
使用验证)。这在浏览器中手动单击时可以正常工作,但在测试期间会失败。而不是被重定向到:
http://localhost/account/create
测试重定向到(缺少斜线):
http://localhostaccount/create
这些网址都不是我在 .htaccess 或 config/app.php 中的 $url
变量中设置的。这是(在 OSX Yosemite):
http://~username/laravel_projects/projectname/public
我最终确定问题与 Request::root()
的结果生成方式有关。在测试之外调用它会产生 .htaccess 和 $url
中定义的预期值。在测试中它导致:
http://localhost
需要更改什么配置才能使此函数在两种情况下都成为 return 正确的值?
我还应该提到我从 Laravel 4 痛苦地升级到当前版本 5.0.27。
****** 更新 *******
我想出了一个可以接受的 solution/workaround 这个问题!
在 Laravel 5 中,引入了 FormRequests 以帮助将 validation 逻辑移出控制器。将请求映射到控制器后,如果指定了 FormRequest
(或仅 Request
),则会在点击控制器操作之前执行。
如果验证失败,默认情况下 FormRequest
会处理响应。它会尝试根据您将表单数据发布到的路由构建重定向。在我的例子中,可能与我从 Laravel 4 更新到 5 的错误有关,这个默认重定向的构造不正确。 Laravel System 处理响应的代码如下所示:
/**
* Get the proper failed validation response for the request.
*
* @param array $errors
* @return \Symfony\Component\HttpFoundation\Response
*/
public function response(array $errors)
{
if ($this->ajax() || $this->wantsJson())
{
return new JsonResponse($errors, 422);
}
return $this->redirector->to($this->getRedirectUrl())
->withInput($this->except($this->dontFlash))
->withErrors($errors, $this->errorBag);
}
请注意 returned 重定向与调用 Redirect::route('some_route')
不同。您可以通过在 Request
class.
中包含 use Response
来 override 这个 response
函数
在使用 Redirect::route()
创建重定向后,我的测试逻辑通过了预期结果。这是我有效的请求代码:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Http\Requests\Request;
use Response;
class AccountRequest extends FormRequest {
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|max:50|email|unique:users',
'password' => 'required|min:6',
'password_confirmation' => 'required|same:password'
];
}
public function response(array $errors){
return \Redirect::route('account_create');
}
}
重要的部分是我调用了 Redirect::route 而不是让默认响应代码执行。
您需要更改 config/app.php
文件的 url
值。默认值为 http://localhost
文档来自 config/app.php
控制台使用此 URL 在使用 Artisan 命令行工具时正确生成 URLs。您应该将其设置为应用程序的根目录,以便在 运行 Artisan 任务时使用它。
我知道这不是您问题的准确答案,因为它不是解决问题的配置更新。但是我一直在努力解决一个相关的问题,这似乎是互联网上唯一一个处理类似问题的人 post - 我想我会为任何想要不同修复的人投入我的两分钱。
请注意,我目前使用的是 Laravel 4.2,因此这可能在 Laravel 5 中发生了变化(尽管我对此表示怀疑)。
您可以在使用函数测试控制器时指定 HTTP_HOST
header:
$response = $this->call($method, $uri, $parameters, $files, $server, $content);
要指定 header,只需提供 $server
变量作为数组,如下所示:
array('HTTP_HOST' => 'testing.mydomain.com');
当我执行上述操作时,为我的 Request::root()
产生的价值是 http://testing.mydomain.com
。
同样,我知道这不是解决您问题的配置更新,但希望这可以帮助那些正在努力解决 semi-related 问题的人。
Override the response function 在 FormRequest 验证处理程序中强制使用 Redirect::route('named_route') 构造重定向,而不是允许默认重定向。
如果您尝试更改 config/app.php
但没有帮助。
最好使用 $_ENV - phpunit 中的全局变量。
说,你想要 Request::root() 到 return 'my.site'
但是你不能触摸phpunit.xml
你可以像这样简单地设置一个环境参数
$_ENV['APP_URL'] = 'my.site';
并在单元测试中调用 $this->refreshApplication();
。
中提琴,你的 request()->root()
现在给你 my.site
。
我定义了一个测试用户创建的测试。控制器设置为在出错时重定向回同一页面(通过生成的 App\Http\Requests\Request
使用验证)。这在浏览器中手动单击时可以正常工作,但在测试期间会失败。而不是被重定向到:
http://localhost/account/create
测试重定向到(缺少斜线):
http://localhostaccount/create
这些网址都不是我在 .htaccess 或 config/app.php 中的 $url
变量中设置的。这是(在 OSX Yosemite):
http://~username/laravel_projects/projectname/public
我最终确定问题与 Request::root()
的结果生成方式有关。在测试之外调用它会产生 .htaccess 和 $url
中定义的预期值。在测试中它导致:
http://localhost
需要更改什么配置才能使此函数在两种情况下都成为 return 正确的值?
我还应该提到我从 Laravel 4 痛苦地升级到当前版本 5.0.27。
****** 更新 *******
我想出了一个可以接受的 solution/workaround 这个问题!
在 Laravel 5 中,引入了 FormRequests 以帮助将 validation 逻辑移出控制器。将请求映射到控制器后,如果指定了 FormRequest
(或仅 Request
),则会在点击控制器操作之前执行。
如果验证失败,默认情况下 FormRequest
会处理响应。它会尝试根据您将表单数据发布到的路由构建重定向。在我的例子中,可能与我从 Laravel 4 更新到 5 的错误有关,这个默认重定向的构造不正确。 Laravel System 处理响应的代码如下所示:
/**
* Get the proper failed validation response for the request.
*
* @param array $errors
* @return \Symfony\Component\HttpFoundation\Response
*/
public function response(array $errors)
{
if ($this->ajax() || $this->wantsJson())
{
return new JsonResponse($errors, 422);
}
return $this->redirector->to($this->getRedirectUrl())
->withInput($this->except($this->dontFlash))
->withErrors($errors, $this->errorBag);
}
请注意 returned 重定向与调用 Redirect::route('some_route')
不同。您可以通过在 Request
class.
use Response
来 override 这个 response
函数
在使用 Redirect::route()
创建重定向后,我的测试逻辑通过了预期结果。这是我有效的请求代码:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Http\Requests\Request;
use Response;
class AccountRequest extends FormRequest {
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|max:50|email|unique:users',
'password' => 'required|min:6',
'password_confirmation' => 'required|same:password'
];
}
public function response(array $errors){
return \Redirect::route('account_create');
}
}
重要的部分是我调用了 Redirect::route 而不是让默认响应代码执行。
您需要更改 config/app.php
文件的 url
值。默认值为 http://localhost
文档来自 config/app.php
控制台使用此 URL 在使用 Artisan 命令行工具时正确生成 URLs。您应该将其设置为应用程序的根目录,以便在 运行 Artisan 任务时使用它。
我知道这不是您问题的准确答案,因为它不是解决问题的配置更新。但是我一直在努力解决一个相关的问题,这似乎是互联网上唯一一个处理类似问题的人 post - 我想我会为任何想要不同修复的人投入我的两分钱。
请注意,我目前使用的是 Laravel 4.2,因此这可能在 Laravel 5 中发生了变化(尽管我对此表示怀疑)。
您可以在使用函数测试控制器时指定 HTTP_HOST
header:
$response = $this->call($method, $uri, $parameters, $files, $server, $content);
要指定 header,只需提供 $server
变量作为数组,如下所示:
array('HTTP_HOST' => 'testing.mydomain.com');
当我执行上述操作时,为我的 Request::root()
产生的价值是 http://testing.mydomain.com
。
同样,我知道这不是解决您问题的配置更新,但希望这可以帮助那些正在努力解决 semi-related 问题的人。
Override the response function 在 FormRequest 验证处理程序中强制使用 Redirect::route('named_route') 构造重定向,而不是允许默认重定向。
如果您尝试更改 config/app.php
但没有帮助。
最好使用 $_ENV - phpunit 中的全局变量。
说,你想要 Request::root() 到 return 'my.site'
但是你不能触摸phpunit.xml
你可以像这样简单地设置一个环境参数
$_ENV['APP_URL'] = 'my.site';
并在单元测试中调用 $this->refreshApplication();
。
中提琴,你的 request()->root()
现在给你 my.site
。