这是我的测试代码:
public function testRegistrationFailsIfNameIsEmpty()
{
$this->flushSession();
$response = $this->call('POST', '/signup', ['fullname' => '']);
$this->assertSessionHasErrors('fullname'); // Passes, expected
$this->assertTrue($response->isRedirection()); // Passes, expected
$this->assertRedirectedTo('/signup'); // Fails, unexpected.
}
当我调用该方法时,它会验证输入,如果验证失败,它会将我重定向回/signup
以显示验证错误。我在浏览器中手动测试了它,它按预期工作。
然而,当我运行上述单元测试时,最后一个断言失败,它认为我被重定向到/
而不是/signup
。
我不知道为什么会这样做。如果我测试发生了重定向,则测试通过,因为重定向发生,它只是认为重定向是/
而不是/signup
。
我已经禁用了所有中间件,所以我知道这不是像访客中间件这样的东西,我认为我已经登录了。
编辑:测试结果:
There was 1 failure:
1) RegistrationTest::testRegistrationFailsIfNameIsEmpty
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'http://localhost/signup'
+'http://localhost'
答案 0 :(得分:6)
如果验证失败,使用request() - > validate()将返回调用URL。运行单元测试时,没有调用页面,因此您将被引导回家。
https://laravel.com/docs/5.5/validation#quick-writing-the-validation-logic
如果验证失败,将抛出异常并出现正确的错误 响应将自动发送回用户。在一个案例中 传统的HTTP请求,将生成重定向响应
因此,您需要测试您的重定向是回家,还是捏造调用网址。虽然那时你只是测试验证器而不是你的代码,但它并没有真正添加任何东西:
session()->setPreviousUrl('/calling/url');
https://www.neontsunami.com/posts/testing-the-redirect-url-in-laravel
编辑: 实际上,当测试期望重定向转到具有命名参数的路由时,这可能很有用。
编辑Laravel 5.8:
应该通过以下方式调用测试:
$this->from('/calling/url')
->get('/some/route')
->assertRedirect('/somewhere/else');
答案 1 :(得分:3)
我在测试Laravel应用时遇到了同样的问题。看来当你在测试中使用$ this->调用然后你的控制器使用类似 Redirect :: back()之类的东西时,重定向会发送到'/'。我相信这是因为当你进行“$ this-> call”时你不在任何页面上,所以应用程序不确定在哪里重定向你,除非你明确指出控制器中的重定向,即重定向('somePage' )。
然而,当执行类似$ this-> actsAs($ user) - > visit('somePage') - > press('someButton')时,您在使用重定向时正确地发送回预期页面: :背部()。可能是因为应用程序知道你开始的页面。
答案 2 :(得分:0)
我建议您在对单个测试进行单元测试时,使用dd()从控制器打印Response对象。这将显示精确重定向的位置。单元测试引擎只解析Response对象,我认为问题出在代码而不是单元测试中。
答案 3 :(得分:0)
您可以检查测试点击控制器中的重定向功能吗? 你可以把一个骰子放在功能中,找出错误在哪里 它应该是方法中的问题。 然后检查它实际进入重定向部分
答案 4 :(得分:0)
您必须设置-> from(route('RouteName')),以确保正确设置了重定向断言
答案 5 :(得分:0)
例如,您要测试请求验证失败。例如,它假设您的用户重定向到先前的URL,且验证失败的异常和一些消息。假设您要更新客户名称。
// --- making a post request ----
$name = 'a new name that is too long';
$route = route('customer.update');
$response = $this
->withSession(['_previous' => ['url' => 'https://google.com']])
->call('POST', $route, [
'_token' => csrf_token(),
'name' => $name,
]);
// --- unit test assertions ----
$response->assertStatus(302);
$response->assertRedirect('https://google.com');
$message = __('@lang_file.some error message text here.');
$expected = [
'default' => ['' => [$message]]
];
$actual = session_errors()->getBags();
$actual = json_encode($actual);
$actual = json_decode($actual, true);
$this->assertSame($expected, $actual);
返回会话错误的函数:
function session_errors(): ViewErrorBag
{
$key = config('session.keys.errors');
$errors = session()->get($key, app(ViewErrorBag::class));
return $errors;
}