单元测试Laravel 5时无法测试重定向

Agm*_*her 8 php unit-testing laravel-5

这是我的测试代码:

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.
}
Run Code Online (Sandbox Code Playgroud)

当我调用该方法时,它会验证输入,如果验证失败,它会将我重定向回/signup显示验证错误.我在浏览器中手动测试了它,它按预期工作.

但是,当我运行上面的单元测试时,最后一个断言失败了,它认为我已被重定向到/而不是/signup.

我不知道它为什么这样做.如果我测试重定向发生了,测试通过,因为重定向确实发生,它只是认为重定向/而不是/signup.

我已经禁用了所有中间件,所以我知道它不像客户中间件,因为我不知道我已经登录了.

编辑:测试结果:

There was 1 failure:

1) RegistrationTest::testRegistrationFailsIfNameIsEmpty
Failed asserting that two strings are equal.

--- Expected
+++ Actual
@@ @@
-'http://localhost/signup'
+'http://localhost'
Run Code Online (Sandbox Code Playgroud)

mar*_*ite 6

如果验证失败,则使用request()-> validate()将返回到调用URL。运行单元测试时,没有调用页面,因此您将被带到首页。

https://laravel.com/docs/5.5/validation#quick-writing-the-validation-logic

如果验证失败,则会引发异常,并且正确的错误响应将自动发送回用户。对于传统的HTTP请求,将生成重定向响应

因此,您要么需要测试您的重定向是到本地,要么伪造调用URL。虽然然后您只是在测试验证器,而不是您的代码,但实际上并没有添加任何内容:

session()->setPreviousUrl('/calling/url');
Run Code Online (Sandbox Code Playgroud)

https://www.neontsunami.com/posts/testing-the-redirect-url-in-laravel

编辑:实际上,当测试期望重定向转到具有命名参数的路由时,这很有用。

编辑Laravel 5.8:

应使用以下命令调用测试:

$this->from('/calling/url')
    ->get('/some/route')
    ->assertRedirect('/somewhere/else');
Run Code Online (Sandbox Code Playgroud)


Mar*_*ala 0

我建议您在对这个单一测试进行单元测试时,使用 dd() 从控制器打印 Response 对象。这将向您显示重定向的具体位置。单元测试引擎只是解析 Response 对象,我相信问题出在代码中而不是单元测试中。