【问题标题】:Cannot test redirects when unit testing Laravel 5单元测试 Laravel 5 时无法测试重定向
【发布时间】:2015-06-19 07:38:10
【问题描述】:

这是我的测试代码:

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'

【问题讨论】:

  • 你的代码有没有调试的可能,否则我建议安装这样的环境,它会有很多次的用处。
  • 如何在浏览器中测试 POST 方法?你确定你没有测试 GET?

标签: php unit-testing laravel-5


【解决方案1】:

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

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

如果验证失败,将抛出异常并出现正确的错误 响应将自动发送回用户。在一个 传统的HTTP请求,会产生一个重定向响应

因此,您要么需要测试您的重定向是否到家,要么伪造调用 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');

【讨论】:

  • 太棒了。在此建议之前,我使用的是->withSession(['_previous' => ['url' => 'https://google.com']])
【解决方案2】:

我在测试 Laravel 应用程序时遇到了同样的问题。似乎当您在测试中使用 $this->call 然后您的控制器使用 Redirect::back() 之类的东西时,重定向被发送到“/”。我相信这是因为当您进行“$this->call”时您不在任何页面上,因此应用程序不确定将您重定向到哪里,除非您明确说明控制器中的重定向,即 redirect('somePage') .

但是,在执行 $this->actingAs($user)->visit('somePage')->press('someButton') 之类的操作时,使用 Redirect::back( )。可能是因为该应用知道您从哪个页面开始。

【讨论】:

    【解决方案3】:

    您必须设置 ->from(route('RouteName')) 以确保正确设置重定向断言

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 我做到了,该位置肯定指向根目录,因此测试显然按预期工作,但现在的问题是为什么重定向在测试环境中返回首页,而在浏览器(本地)它会去它应该去的地方。我检查了浏览器中的请求流量,没有中间重定向回家然后回到 /signup,所以我不确定它为什么会这样。此外,没有错误日志表明正在抛出 500 并且由于某种原因重定向回家。
      • 当您在控制器中 dd() 之前返回时,您的 RedirectResponse 看起来如何?它应该显示 targetUrl 和 statusCode 告诉你它被重定向到哪里。这有助于您了解从哪里开始查找问题所在。
      【解决方案5】:

      你能检查一下控制器中的重定向功能的测试吗 您可以在函数中放置一个骰子并找出错误在哪里 应该是方法的问题。 然后检查它实际上进入了重定向部分

      【讨论】:

        【解决方案6】:

        例如你想测试一个请求验证失败。例如,它假设将您的用户重定向到以前的 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;
         }
        

        【讨论】:

          猜你喜欢
          • 2016-07-18
          • 1970-01-01
          • 2010-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-01
          • 1970-01-01
          • 2017-11-02
          相关资源
          最近更新 更多