Laravel 4 controller tests - ErrorException after too many $ this-> call() - 为什么? [英] Laravel 4 controller tests - ErrorException after too many $this->call() - why?

查看:181
本文介绍了Laravel 4 controller tests - ErrorException after too many $ this-> call() - 为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我非常感谢您对我遇到的Laravel 4问题的一些帮助。



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



为所有场景编写,直到现在工作正如预期使用PHPunit。我目前写的测试涉及几个 $ this-> call() $ this-> client-> request() / code>执行,这就是事情分解。如果我执行 $ this-> call() $ this-> client-> request()在一个单一的测试方法中,我得到一个ErrorException的太多次(2个或更多具体)在终端:


{error :{type:ErrorException,message:未定义的变量:header,file:/ Volumes / Dev HD / dmh / app / views / layouts / steps.php,line:1 }}


如果我减少 $ this-> call c>或 $ this-> client-> request()在测试方法中一个,事情工作,没有显示异常。我一直在使用以下代码:



代码



  ** 
*当用户跳过问题,他们还没有回答,用户
*应重定向回第一个未回答的问题。
*
* @return void
* /
public function testDiscoverSkipQuestions()
{
//获取第一个问题。
$ domCrawler = $ this-> client-> request('GET','style / discover');

//回答第一个问题
$ form = $ domCrawler-> selectButton(Next») - > form
$ form ['question_1'] ='A:0';
$ response = $ this-> client-> submit($ form);
$ this-> assertRedirectedTo('style / discover / 2');

//获取第5个问题。
$ this-> call('GET','style / discover / 5');
// BROKEN

//期望被重定向到第二个问题。
$ this-> assertRedirectedTo('style / discover / 2');
$ this-> assertSessionHas('attention');
}



任何想法?



我需要重置某些东西才能打几个电话吗?这是做这样几个电话的坏习惯吗?有没有更好的方式来写这个测试?



非常感谢。

解决方案

Probable Solution:



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



说明/详情:



好吧,这里是兔子洞:D


  1. Laravel TestCase 扩展灯光效果\Foundation\Testing\TestCase

  2. Illuminate \ Foundation\Testing\Client 发出假请求。

  3. Illuminate \Foundation\Testing\Client 扩展 Symfony \Component\HttpKernel\Client a>

  4. Symfony \ Component\HttpKernel\Client 扩展抽象类 Symfony \\ \\Component\BrowserKit\ Client

  5. 抽象类 Symfony \Component\BrowserKit\客户端有一个方法 restart()

我没有亲自测试这个),你应该能够做到以下:

  / ** 
*当用户跳过问题,他们还没有回答,用户
*应该重定向回第一个未回答的问题。
*
* @return void
* /
public function testDiscoverSkipQuestions()
{
//获取第一个问题。
$ domCrawler = $ this-> client-> request('GET','style / discover');

//回答第一个问题
$ form = $ domCrawler-> selectButton(Next») - > form
$ form ['question_1'] ='A:0';
$ response = $ this-> client-> submit($ form);
$ this-> assertRedirectedTo('style / discover / 2');

// ********重新启动新请求********
$ this-> client-> restart();

//获取第5个问题。
$ this-> call('GET','style / discover / 5');
// ********应该现在工作 - call()是$ this-> client-> request()的代理; ********

//期望被重定向到第二个问题。
$ this-> assertRedirectedTo('style / discover / 2');
$ this-> assertSessionHas('attention');注意,call()方法为 a href =https://github.com/laravel/framework/blob/master/src/Illuminate/Foundation/Testing/TestCase.php#L56>使用 $ this-> client-> request()



希望有所帮助!不要害怕挖掘代码继承,看看是否存在一个方便的方法来做你需要的 - 更改常常已经存在:D



改进(?)



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


I'd greatly appreciate some help regarding a Laravel 4 issue I'm experiencing.

I'm testing controller routes, specifically a controller that is responsible for routing responses for a questionnaire. I'm testing scenarios such as: the user attempting to skip a question, the user requesting a question that doesn't exist... etc.

The tests that I've written for all scenarios up until now work as expected using PHPunit. The test I'm currently writing involves several $this->call() or $this->client->request() executions and that's where things break down. If I execute $this->call() or $this->client->request() too many times (2 or more to be specific) in a single test method I get an ErrorException in the terminal:

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

If I reduce the quantity of $this->call() or $this->client->request() in the test method to one, things work, and no exception is shown. I've been using the following code:

Code

/**
 * 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');
}

Any ideas?

Do I need to reset something in order to make several calls? Is this bad practice for making several calls like this? Is there a better way to write this test? Any ideas would be greatly appreciated.

Thanks a bunch!

解决方案

Probable Solution:

Use $this->client->restart() to start a new request.

Explanation/Detail:

OK so, here's the rabbit hole :D

  1. Laravel TestCase extends Illuminate\Foundation\Testing\TestCase
  2. Illuminate\Foundation\Testing\TestCase uses Illuminate\Foundation\Testing\Client to make the fake requests.
  3. Illuminate\Foundation\Testing\Client extends Symfony\Component\HttpKernel\Client
  4. Symfony\Component\HttpKernel\Client extends abstract class Symfony\Component\BrowserKit\ Client
  5. Abstract class Symfony\Component\BrowserKit\ Client has a method restart()

So, I believe in your case (I haven't personally tested this), you should be able to do the following:

/**
 * 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');
}

Note that the call() method is a proxy to using $this->client->request()

Hope that helps! Don't be afraid to dig into code inheritances to see if a convenience method exists to do what you need - changes are it often already exists :D

Improvement(?)

Note that these tests might lean more towards "integration tests" rather than "unit tests". Integration tests may be a better fit when used with continuous integration frameworks. See this question for some more info.

这篇关于Laravel 4 controller tests - ErrorException after too many $ this-> call() - 为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆