Skip to content

Instantly share code, notes, and snippets.

@fians
Created September 5, 2020 16:45
Show Gist options
  • Save fians/b17b8a87daa798b6c5b5b5dd9360cc67 to your computer and use it in GitHub Desktop.
Save fians/b17b8a87daa798b6c5b5b5dd9360cc67 to your computer and use it in GitHub Desktop.
Warning: assertExactJson() doesn't respect order of elements on Laravel v7.x (or older)

Warning: assertExactJson() doesn't respect order of elements on Laravel v7.x (or older)

While I was working on a project using Laravel, I noticed that assertExactJson() do sorting on ordered array that I set on api response. Then I stumbled upon a PR from @mnabialek that also mention the same problem (see: laravel/framework#33672). This means you might need to check again your code that use assertExactJson.

The PR itself has been merged, but it merged to the next version of Laravel (v8.x, at the time this writing) and also since Laravel team need to keep their backward compatibility, this fix will not landed on the older version of Laravel (<v8.x). So, I made this gist to fix assertExactJson() in your Laravel v7.x (or older). All you need to do is add createTestResponse() on your existing test\TestCase.php and TestResponse.php on tests folder.

<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
/**
* Overide createTestResponse() from Illuminate\Foundation\Testing\Concerns\MakesHttpRequests trait
* to fix assertExactJson implementation. See: https://github.com/laravel/framework/pull/33672
*
* @param \Illuminate\Http\Response $response
* @return \Illuminate\Foundation\Testing\TestResponse
*/
protected function createTestResponse($response)
{
return TestResponse::fromBaseResponse($response);
}
}
<?php
namespace Tests;
use Illuminate\Support\Arr;
use Illuminate\Foundation\Testing\Assert;
class TestResponse extends \Illuminate\Foundation\Testing\TestResponse
{
/**
* Assert that the response has the exact given JSON.
*
* @param array $data
* @return $this
*/
public function assertExactJson(array $data)
{
$actual = $this->reorderAssocKeys((array) $this->decodeResponseJson());
$expected = $this->reorderAssocKeys($data);
Assert::assertEquals(json_encode($expected), json_encode($actual));
return $this;
}
/**
* Reorder associative array keys to make it easy to compare arrays.
*
* @param array $data
*
* @return array
*/
protected function reorderAssocKeys(array $data)
{
$data = Arr::dot($data);
ksort($data);
$result = [];
foreach ($data as $key => $value) {
Arr::set($result, $key, $value);
}
return $result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment