Testing Laravel JSON requests

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.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top