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:
/**
* 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');
}
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!
Use $this->client->restart()
to start a new request.
OK so, here's the rabbit hole :D
TestCase
extends Illuminate\Foundation\Testing\TestCase
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With