Laravel 4控制器测试 - 在过多$ this-> call()之后出现ErrorException - 为什么?

dbr*_*428 5 testing phpunit controller laravel laravel-4

对于我正在经历的Laravel 4问题,我非常感谢.

我正在测试控制器路由,特别是负责路由问卷调查的控制器.我正在测试以下场景:用户试图跳过问题,用户请求不存在的问题......等等.

我为所有场景编写的测试到目前为止使用PHPunit按预期工作.我正在编写的测试涉及多个$this->call()$this->client->request()执行,这就是事情发生的地方.如果我在一个测试方法中执行$this->call()或执行$this->client->request()太多次(特定于2或更多),我会在终端中获得ErrorException:

{"error":{"type":"ErrorException","message":"Undefined variable:header","file":"/ Volumes/Dev HD/dmh/app/views/layouts/steps.php","行":1}}

如果我减少的数量$this->call()$this->client->request()测试方法一,工作上的事情,并没有显示异常.我一直在使用以下代码:

/**
 * When the user skips questions they have not yet answered, the user 
 * should be redirected back to the first unanswered question.
 *
 * @return void
 */
public function testDiscoverSkipQuestions()
{
    // Get the first question.
    $domCrawler = $this->client->request('GET', 'style/discover');

    // Answer the first question
    $form = $domCrawler->selectButton("Next »")->form();
    $form['question_1'] = 'A:0';
    $response = $this->client->submit($form);
    $this->assertRedirectedTo('style/discover/2');

    // Get the 5th question.
    $this->call('GET', 'style/discover/5');
    // BROKEN

    // Expect to be redirected to the 2nd question.
    $this->assertRedirectedTo('style/discover/2');
    $this->assertSessionHas('attention');
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

我是否需要重置某些内容才能拨打多个电话?做这样的几个电话这是不好的做法吗?有没有更好的方法来编写这个测试?任何想法将不胜感激.

谢谢你!

fid*_*per 14

可能的解决方案:

使用$this->client->restart()开始新的请求.

说明/详细信息:

好吧,这是兔子洞:D

  1. Laravel TestCase扩展了Illuminate\Foundation\Testing\TestCase
  2. Illuminate\Foundation\Testing\TestCase使用Illuminate\Foundation\Testing\Client来发出虚假请求.
  3. Illuminate\Foundation\Testing\Client扩展Symfony\Component\HttpKernel\Client
  4. Symfony\Component\HttpKernel\Client扩展抽象类Symfony\Component\BrowserKit\Client
  5. 抽象类Symfony\Component\BrowserKit\Client有一个方法restart()

所以,我相信你的情况(我没有亲自测试过这个),你应该能够做到以下几点:

/**
 * When the user skips questions they have not yet answered, the user 
 * should be redirected back to the first unanswered question.
 *
 * @return void
 */
public function testDiscoverSkipQuestions()
{
    // Get the first question.
    $domCrawler = $this->client->request('GET', 'style/discover');

    // Answer the first question
    $form = $domCrawler->selectButton("Next »")->form();
    $form['question_1'] = 'A:0';
    $response = $this->client->submit($form);
    $this->assertRedirectedTo('style/discover/2');

    // ******** Restart for new request ********
    $this->client->restart();

    // Get the 5th question.
    $this->call('GET', 'style/discover/5');
    // ******** SHOULD NOW WORK - call() is a proxy to $this->client->request(); ********

    // Expect to be redirected to the 2nd question.
    $this->assertRedirectedTo('style/discover/2');
    $this->assertSessionHas('attention');
}
Run Code Online (Sandbox Code Playgroud)

请注意,call()方法是使用的代理$this->client->request()

希望有所帮助!不要害怕深入挖掘代码遗传,看看是否存在一种方便的方法来做你需要的东西 - 变化通常已经存在:D

改进(?)

请注意,这些测试可能更倾向于"集成测试"而不是"单元测试".与持续集成框架一起使用时,集成测试可能更适合.有关更多信息,请参阅此问题.