Chased a stupid problem all day today. Long story short: I had a simple Laravel controller that was trying to just echo back the inputs from a JSON request body. It’s not enough to write a test like the following.
Wrong Code:
class MyTest extends TestCase {
function test_example() {
$this->withHeaders([
'Accept' => 'application/json',
'Content-Type' => 'application/json',
])->post('echo', ['foo' => 'bar'])->assertJson(['foo' => 'bar']);
}
}Code language: PHP (php)
The controller tries to read $request->all(), which is empty! That’s because of how the Laravel test framework constructs request objects. It doesn’t care that I provided those headers to indicate that there was a JSON body to draw from. You have to use postJson instead of post for that, and then you don’t need those headers, either.
Correct:
function test_example() {
$this->postJson('echo', ['foo' => 'bar'])->assertJson(['foo' => 'bar']);
}Code language: PHP (php)
The same is true for patch vs. patchJson. So somehow, I’ve been using the wrong method all this time, and it’s never been a problem? I’m shocked and confused.