【问题标题】:Laravel 4 phpunit test: Test flagged as `risky` for not closing its own output buffersLaravel 4 phpunit 测试:测试标记为“风险”,因为没有关闭自己的输出缓冲区
【发布时间】:2014-08-15 20:12:55
【问题描述】:

我在尝试在 phpunit 测试中测试简单的 Illuminate\Http\Response 对象时遇到问题。有问题的错误是:

PHPUnit 4.3-dev by Sebastian Bergmann.

Configuration read from /var/MyApp/phpunit.xml

....................R.................

Time: 2.71 seconds, Memory: 76.75Mb

OK, but incomplete, skipped, or risky tests!
Tests: 38, Assertions: 55, Risky: 1.     

phpunit --tap as 运行时显示 R 的位置

# RISKY Test code or tested code did not (only) close its own output buffers

我要测试的类是:

class PrettyError {

    /**
     * Renders a pretty 500 error page view
     *
     * @return string with error view
     */
    public function render()
    {
             return Response::make(View::make('viewName')->with('param','value')->render(), 500, array());
    }
}

测试是

class Pretty500Test extends BaseTest {

    /** @var Pretty500 */
    private $pretty500;

    /**
     * Set dependencies
     */
    public function __construct()
    {
        $this->pretty500 = app(PrettyError::class);
    }

    public function testRender()
    {
        $response = $this->pretty500->render();

        //assertions below, never get reached cause tests aborts after above call
        $this->assertsTrue('500',$response->getStatus());
    }

}    

请注意,使用 laravel 在我的应用程序中测试任何路线时都会发生相同的错误

this->route('GET','routeName')

helper 方法,所以这似乎是与响应请求相关的一般错误。据我所知,我的应用程序中没有任何东西在输出缓冲(有目的地)做任何时髦的事情,这是我能想到的唯一可能会破坏 Response 类的标准工作的事情。

我正在使用 phpunit 4.3-dev、laravel 4.2.1 和 mocky 进行测试。

就这个特别危险的错误代码而言,我在互联网上根本没有找到太多信息,所以如果没有进一步的帮助,我会不知所措。

【问题讨论】:

  • 在全新安装的 Laravel 上尝试一下 - 你仍然遇到问题吗?
  • 不,我还没有尝试过全新安装,接下来我会这样做,以确保它不在我正在使用的 TestCase 设置中
  • 更新:我将问题隔离了一点,它与 Request 类本身无关,而是与内部 View 调用有关,所以基本上View::make('viewName')->with('param','value')->render() 触发了 phpunit 风险警告,没有任何其他内容测试。由于我的应用程序中的 View 实例不是本机 laravel 实例,而是使用自定义实例进行热交换,但建立在此之上(它注册了一些有用的 View 作曲家),也许其中有一些测试不喜欢的东西
  • 实际上 - 我刚刚注意到您正在“制作”一个视图,渲染它,然后将其发送到 Response 类以重新渲染?
  • 是的,基本上我正在创建一个带有自定义标题和状态代码的响应,它的内容只是呈现的视图。我现在看了一下文档,有一个速记方法Response::view('hello')->header('Content-Type', $type); 可以立即使用它,但除此之外它是正确的 AFAIK

标签: laravel laravel-4 phpunit


【解决方案1】:

原来问题是由于使用了有问题的视图

Input::old()

在表单中。在尝试在任何 phpunit 测试中简单地访问 Input::old('foo') 后,我得到了一个

RuntimeException: Session store not set on request.

所以真正的罪魁祸首是在我的单元测试中的会话存储中,而不是任何请求/视图渲染问题。通过在 testRender() 方法中为当前 Request 实例设置会话存储解决了问题:

\Illuminate\Support\Facades\Request::setSession($this->app['session.store'])

【讨论】:

    【解决方案2】:

    我遇到了非常相似的问题。问题是我试图在视图中获取非对象(NULL)的属性,而不是 PHP 错误“试图获取非对象的属性”phpunit 显示“好的,但不完整、跳过或有风险的测试!” .

    因此,如果您遇到同样的问题,请检查视图文件中的此类错误。

    【讨论】:

      【解决方案3】:

      也发生在 Laravel 5 中。
      当响应格式不正确时,PHPUnit 会抛出这个。

      这可能是由于:

      • Laravel 应用中的错误:检查日志
      • 不正确的 Blade 语法:例如在我的例子中,有一个过多的 Blade @stop 被 Laravel 不认为是错误(并且没有被记录)

      【讨论】:

      • 与我的安装相同。没有 @endsection 来关闭我的模板文件中打开的部分。
      • 也只是想插话。我在为 Laravel 5.1app 编写测试时遇到了这个令人发狂的风险问题。这条评论让我走上了正确的道路,事实证明我在 Blade 模板中有一个过时的 @show 语句,这导致了问题。如果您想在您的 Laravel 应用程序(或与此相关的任何应用程序)中查找至少包含一个 @endsection 语句的所有文件,请运行以下命令: grep -cr "@endsection" 。 | sed '/:0$/d' | sort -k2n -t:这很有用,因为 grep 的默认行为是列出 所有 个文件和出现次数。
      【解决方案4】:

      我有来自 PhpUnit 的相同错误消息,喜欢你的。我在视图(刀片)文件的错误行上写了 '@stop'。我通过将右 '@stop' 移动到右行进行了编辑,而不是 PHPUnit 测试通过了!

      尝试检查刀片文件中的 @section @stop 块。

      【讨论】:

        【解决方案5】:

        封闭式三元运算符 (?) 不够好

        在 Laravel 5 中进行测试时,我遇到了同样的风险测试用例问题。这里的问题是,我的导航(默认布局文件)中有如下代码:

        <li{{ Request::is('clients*')?' class="active"':'' }}><a href="/clients">Clients</a></li>
        

        测试不喜欢这部分,因为三元运算符(?)关闭得不够好。我将其替换为以下内容以使其正常工作(在三元运算符部分周围添加了括号):

        <li{{ (Request::is('clients*')?' class="active"':'') }}><a href="/clients">Clients</a></li>
        

        我通过从请求的视图、它扩展的布局和包含的文件中逐部分删除刀片语法找到了这一点。在删除上面的语法时它起作用了,所以出现了错误。

        空产量/节

        当我为收益传递一个空值时,发生了同样的错误,例如在以下场景中:

        layout.blade.php

        <h1>@yield('title')</h1>
        

        page.blade.php

        @extends('layout')    
        @section('title','') //<-- This empty value raised the error
        

        其他需要考虑的事项

        也许很清楚,但以防万一您犯了同样的错误:您必须检查所有涉及的文件。

        我运行了以下测试,访问登录页面,输入电子邮件和密码并按下登录按钮:

        测试/AuthenticationTest.php

        <?php
        class AuthenticationTest extends TestCase
        {
            // [...]
        
            public function testLoginSuccessful()
            {
                $password = str_random();
        
                $user = factory(App\User::class)->create(['password' => $password]);
        
                $this->visit(route('login'))
                    ->type($user->email, 'email')
                    ->type($password, 'password')
                    ->press('Login')
                    ->seePageIs(route('dashboard2'));
            }
        }
        

        app/Http/routes.php

        <?php
        Route::get('auth/login',    'Auth\AuthController@getLogin')->name('login');
        Route::post('auth/login',   'Auth\AuthController@postLogin');
        

        app/Http/Controllers/Auth/AuthController.php

        <?php    
        // [...]
        class AuthController extends Controller
        {
            // [...]
        
            protected $redirectPath = '/dashboard2'; // <-- check this file as well
        }
        

        所以我必须特别检查以下我进行修改的文件:

        • app/Http/routes.php
        • app/Http/Controllers/Auth/AuthController.php -> 函数getLogin
        • resources/views/auth/login.blade.php(在 Auth\AuthContoller@getLogin 中返回)
        • app/Http/Controllers/Auth/AuthController.php -> 函数postLogin
        • resources/views/dashboard2.blade.php(登录成功后返回)

        【讨论】:

        • 空白部分也引起了我的注意。将其更改为 @section('name', null) 使其没有风险,但现在看起来像代码异味:-/
        • @section('title','') 引起了问题。谢谢!
        • 对我来说,我必须将 @section('title') 包装在 @hasSection 块中 - 使用 null 而不是 '' 并没有成功。
        【解决方案6】:

        重复的@section('content') 行有同样的问题

        @section('content')
        
        @section('content')
        ...
        @endsection
        

        错字!!

        【讨论】:

          猜你喜欢
          • 2017-04-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-19
          • 1970-01-01
          • 2016-11-13
          • 1970-01-01
          • 2015-10-14
          相关资源
          最近更新 更多