Laravel 4 controller tests - ErrorException after too many $ this-> call() - 为什么? [英] Laravel 4 controller tests - ErrorException after too many $this->call() - why?
问题描述
我非常感谢您对我遇到的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
- Laravel
TestCase
扩展灯光效果\Foundation\Testing\TestCase - Illuminate \ Foundation\Testing\Client 发出假请求。
- Illuminate \Foundation\Testing\Client 扩展 Symfony \Component\HttpKernel\Client a>
- Symfony \ Component\HttpKernel\Client 扩展抽象类 Symfony \\ \\Component\BrowserKit\ Client
- 抽象类 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
- Laravel
TestCase
extends Illuminate\Foundation\Testing\TestCase
- Illuminate\Foundation\Testing\TestCase uses Illuminate\Foundation\Testing\Client to make the fake requests.
- Illuminate\Foundation\Testing\Client extends Symfony\Component\HttpKernel\Client
- Symfony\Component\HttpKernel\Client extends abstract class Symfony\Component\BrowserKit\ Client
- 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屋!