Skip to content

Instantly share code, notes, and snippets.

@Oldenborg
Last active October 2, 2023 22:50
Show Gist options
  • Save Oldenborg/dbea4eb6df6cabf388310e6b0168262f to your computer and use it in GitHub Desktop.
Save Oldenborg/dbea4eb6df6cabf388310e6b0168262f to your computer and use it in GitHub Desktop.
Laravel test trait: assert JSON exact
<?php
namespace Tests\Traits;
use Illuminate\Testing\TestResponse;
use Illuminate\Support\Arr;
use PHPUnit\Framework\Assert as PHPUnit;
trait AssertJson
{
/* @before */
public function setUp(): void
{
parent::setUp();
$this->setUpAssertJson();
}
public function setUpAssertJson(): void
{
TestResponse::macro('assertJsonStructureExact', function (array $structure = null, $responseData = null) {
$transformStructure = function ($structure, $prefix = '') use (&$transformStructure) {
$result = [];
foreach ($structure as $key => $value) {
if (is_array($value) && array_keys($value) !== range(0, count($value) - 1)) {
$result = array_merge($result, $transformStructure($value, $prefix . $key . '.'));
} elseif (is_array($value)) {
foreach ($value as $k) {
$result[] = $prefix . $key . '.' . $k;
}
} else {
$result[] = $prefix . $value;
}
}
return $result;
};
$expectedKeys = $transformStructure($structure);
sort($expectedKeys);
if ($responseData === null) {
$responseData = json_decode($this->getContent(), true);
}
$responseKeys = Arr::dot($responseData);
$responseKeys = array_keys($responseKeys);
sort($responseKeys);
$missingKeys = array_diff($expectedKeys, $responseKeys);
$extraKeys = array_diff($responseKeys, $expectedKeys);
$errorMessage = "";
if (!empty($extraKeys)) {
$prettyList = "[\n '" . implode("',\n '", $extraKeys) . "'\n]";
$errorMessage .= "The response had the following unexpected parameters:\n" . $prettyList . ".";
}
if (!empty($missingKeys)) {
$prettyList = "[\n '" . implode("',\n '", $missingKeys) . "'\n]";
$errorMessage .= "The response is missing the following parameters:\n" . $prettyList . ".";
}
PHPUnit::assertTrue(empty($missingKeys) && empty($extraKeys), $errorMessage);
return $this;
});
}
}
@Oldenborg
Copy link
Author

Oldenborg commented Oct 2, 2023

I have finally taken the time to update this Trait so it works with the lastest version of Laravel (10)

At the same time, I have implemented more meaningful error messages that will be visible in the console.

   FAILED  Tests\Feature\AuthenticationTest > a guest can register                          
  The response had the following unexpected parameters:
[
    'data.token',
    'data.user.created_at',
    'data.user.email_verification_token',
    'data.user.updated_at'
],
The response is missing the following parameters:
[
    'status'
].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment