Before I get started, I'd like to say that I've already looked at Failed asserting the HTTP status is 200 not 500 as well as Failed asserting the HTTP status code is 200 not 500. Do not let the names fool you; they are 2 different posts. Both of these posts are older than 9 months and have no good answers.
I'm having some trouble testing routes. So, I made a new Laravel 5 project on my Mac Mini running OS X Yosemite 10.10.2. I'm making an API. So, I started making the backend part of the API first. I decided that I wanted to use PHPUnit to implement TDD for this project. My version of PHPUnit is 4.0.20. I'm running PHP 5.5.14 and I'm using the server packaged with Laravel in the artisan command line tool.
Now, I started with making sure that I could just connect to the server. So, my first test looks like:
public function testGetMessagesResponse()
{
$response = $this->call('GET', 'Messages');
$this->assertEquals(200, $response->getStatusCode());
}
This passes just fine. However, when I moved on to the POST request, it failed. This is what my second test looks like:
public function testPostMessagesResponse()
{
$response = $this->call('POST', 'Messages');
$this->assertEquals(200, $response->getStatusCode());
}
This test fails. Here is what the output looks like:
1) MessagesTest::testPostMessagesResponse
Failed asserting that 500 matches expected 200.
In my routes.php file, I do have this route registered:
Route::resource('Messages', 'MessagesController');
In my MessagesController, I have all the required methods:
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class MessagesController extends Controller {
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return 'response';
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
return 'response';
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
return 'response';
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
return 'response';
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
return 'response';
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
return 'response';
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
return 'response';
}
}
So, for the time being, no matter the HTTP verb, I should get 'response'. Now, I decided to verify the test with curl:
curl -X POST http://myapp.com/Messages
This returns the Laravel 'Oops!' page. So there is indeed some kind of server error, but I'm not sure what to look for. The application flow looks good, but it obviously is not working. Here is the stack trace from my Laravel log:
[timestamp] local.ERROR: exception 'Illuminate\Session\TokenMismatchException' in /Users/username/Sites/project/storage/framework/compiled.php:2375
Stack trace:
#0 /Users/username/Sites/project/app/Http/Middleware/VerifyCsrfToken.php(17): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#1 /Users/username/Sites/project/storage/framework/compiled.php(8858): App\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#2 /Users/username/Sites/project/storage/framework/compiled.php(11990): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#3 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#4 /Users/username/Sites/project/storage/framework/compiled.php(10696): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#5 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#6 /Users/username/Sites/project/storage/framework/compiled.php(11696): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#7 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#8 /Users/username/Sites/project/storage/framework/compiled.php(11645): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#9 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#10 /Users/username/Sites/project/storage/framework/compiled.php(2411): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#11 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#12 [internal function]: Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#13 /Users/username/Sites/project/storage/framework/compiled.php(8849): call_user_func(Object(Closure), Object(Illuminate\Http\Request))
#14 /Users/username/Sites/project/storage/framework/compiled.php(1862): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#15 /Users/username/Sites/project/storage/framework/compiled.php(1852): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#16 /Users/username/Sites/project/public/index.php(53): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#17 /Users/username/Sites/project/server.php(21): require_once('/Users/username/Site...')
#18 {main}
I'm pretty new to Laravel and so I'm not sure how to really dig in and use the stack trace to figure out what is going wrong. I have also tried this without Route::resource, but this does not alleviate my situation. My GET still works just fine (Route::get), but my POST (Route::post) is still getting that same 500 error. The function encompassing line 2375 in .../compiled.php (from the exception thrown at the top of the stack trace) is generated by Laravel and looks like this:
public function handle($request, Closure $next)
{
if ($this->isReading($request) || $this->tokensMatch($request)) {
return $this->addCookieToResponse($request, $next($request));
}
throw new TokenMismatchException();
}
At that point, I tried to edit the POST test, since I wasn't actually sending any data. So here is my revised second test:
public function testPostMessagesResponse()
{
$response = $this->call('POST', 'Messages', array("key" => "value"));
$this->assertEquals(200, $response->getStatusCode());
}
I get the same error message. I feel like I'm missing something simple, but I cannot figure it out. Any help would be greatly appreciated.