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

标签 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.
}

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

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

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

我已经禁用了所有中间件,所以我知道它不像 guest 中间件那样认为我在未登录时已登录。

编辑:测试结果:

There was 1 failure:

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

--- Expected
+++ Actual
@@ @@
-'http://localhost/signup'
+'http://localhost'

最佳答案

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

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

if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user. In the case of a traditional HTTP request, a redirect response will be generated

所以你要么需要测试你的重定向是否到家,要么捏造调用 url。虽然那样你只是在测试验证器而不是你的代码,它并没有真正添加任何东西:

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');

关于php - 单元测试 Laravel 5 时无法测试重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29614722/

相关文章:

php - 如果重复,如何在用户名末尾添加额外的数字

php - htaccess 重定向网站

java - 我们如何从基类中检索接口(interface)并测试它?

php - 拉维尔 : is it possible to set a controller dynamically for a route?

laravel - 我的 Laravel 5.4 登录用户 session 不会持续存在

php - Laravel 5.2 自定义用户权限检查

php - 在 Symfony 1.4 和 Doctrine 中使用一个查询插入多行

php - 从数据库读取数据出错

java - FEST:如何正确使用NoExitSecurityManager?

c# - NCover:从覆盖范围中排除不可执行的代码行