5

对于我遇到的 Laravel 4 问题,我将不胜感激。

我正在测试控制器路由,特别是负责路由问卷响应的控制器。我正在测试场景,例如:用户试图跳过一个问题,用户请求一个不存在的问题......等等。

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

{"error":{"type":"ErrorException","message":"未定义变量: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');
}

有任何想法吗?

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

非常感谢!

4

1 回答 1

14

可能的解决方案:

用于$this->client->restart()启动新请求。

说明/细节:

好的,这是兔子洞:D

  1. LaravelTestCase扩展了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');
}

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

希望有帮助!不要害怕深入研究代码继承,看看是否存在方便的方法来做你需要的事情 - 更改它通常已经存在:D

改进(?)

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

于 2013-07-07T20:43:36.740 回答