Hi here a few tips to work on testing with Laravel, this post will be always on updating to grow.
Get form request/request validate errors as JSON for an API
Use the testCase method "json()"
$this->json('post', '/api/any', ['key' => 'value']);
If you are making an ajax or fetch request the errors will be displayed as json by default, to tests this validation errors just use the "json()" method.
Create a Request class
This is particularly helpful if you are using dependency injection.
- To create a request class and add params
$request = new \Illuminate\Http\Request();
$request->replace([
"name" => "John Doe",
"email" => "john@doe.com",
]);
- It works also for a form request class:
$request = new FormRequestCustomClass();
$request->replace([
"name" => "John Doe",
"email" => "john@doe.com",
]);
Read a JSON response content easy.
You can chain "json()" method with "getContent()" method that allow you to view the response content, typically a convention is to hold the response in a variable to make some assertions, in this case as you wish to view response in JSON format you can use "json_encode()" php native function to get a better readability:
$response = $this->json('get', '/api/anyendpoint');
dd(json_decode($response->getContent()));
It works for other methods to make a request like "get()", "post()", "put()", "delete()", but it has more sense in "json()" method because it returns a JSON.
Another way to inspect the response is with the method "dump":
$response->dump();
Testing redirects
Typically in your controller you could return a redirect response in different ways:
return redirect('/users'); // case 1 not the best approach
return redirect->to('/users'); // case 2 still not the best
return redirect()->route('users); // case 3 a good practice
return redirect()->back(); // case 4 if your previous endpoint was "/users" this is fine
Well, to test the redirect in many cases you can do something like:
$response->assertRedirect('/users'); // this works for case 1, 2, 3
$response->assertRedirect(route('users')); // this works for case 1, 2, 3
As you can see the only method that cant be tested easily is the one that use the helper "back()", Laravel can test the "redirect" method if this add a explicit route, so the 4 case only will work by testing only the redirect status, like:
$response->assertStatus(302);
$response->assertRedirect();
This maybe is not a granular test because we are only testing that a redirect is being executed, but this applies when you need to use the "back()" helper that is particularly useful in some situations.
Count items from a JSON response:
In any response you can return a json if this is a collection or a resource collection like:
$users = User::all();
// or
$users = UserResource::collection(User::all());
// or
$users = new UserResourceCollection(User::all());
The Json response would return a nested items one for every user in the collection:
{
"data": {
{
"name": "John Doe",
"email": "john@doe.com"
},
{
"name": "Anne Doe",
"email": "anne@doe.com"
},
{
"name": "Marie Doe",
"email": "marie@doe.com"
},
}
}
Then probable you would like to assert the total of items inside the data, well this is a very useful tip, the Laravel response has a method JsonCount() method, this would help to count the items in a JSON response:
If is an eloquent collection:
$response->assertJsonCount(5);
If is a resource collection:
$response->assertJsonCount(5, 'data');
Why add data? because the resources return all data formatted as you wish in a JSON with a 'data' key, so it will count the items (users) inside the data key.
Test API endpoints:
The rest standard requires to get data as:
fetch.get('/endpoint')
.then(response => {
const data = response.data
})
Usually the structure of any request requires a response object with data property, but Laravel resources add another data property to the response, to remove this other property and stay with API REST standard, Laravel provides a method to remove this other property, "withoutWrapping":
return new UserResource(User::first())->withoutWrapping();
Thanks for reading, you are welcome to add comments to add more test tips!
Top comments (0)