0

I have a laravel API project. There is a lot security data, that shouldn't be shown for users in API responses. I need some way to write tests where I can get true if only the response structure is exact same as a pre-set structure in test.

So, if my test structure is $structure = [ 'data' => ['_id', 'user' => ['name', 'email], 'title']; but in response I'm recieveing more or less fields, I need this test to be failed.

In a docs I've found only:

assertJson - expecting for exact key => values, but I need a keys only; assertJsonStructure - returns true even if some fields missing or response contains some other fields.

3
  • you can make a custom function for that Commented Oct 3, 2019 at 13:37
  • @N69S sure I can. But I'm looking for something existing first. Commented Oct 3, 2019 at 13:51
  • Do you want to test only the structure or also the data? If you want to test the data you can use $this->assertEquals(..., ...), if you want to be sure that some values is not shown you can use $this->assertArrayNotHasKey(); Commented Oct 3, 2019 at 14:56

2 Answers 2

1

Use Opis JSON Schema

$validator = new \Opis\JsonSchema\Validator();
$result = $validator->dataValidation($json, $schema);
PHPUnit::assertTrue($result->isValid(), "Mismatch json schema");

For your case read more about required and additionalProperties: https://docs.opis.io/json-schema/1.x/object.html#required

Your json scheme may be looks like:

{
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id"
      ],
      "properties": {
        "id": {
          "type": "integer"
        }
      }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Looks good. Can I require embedded structures? Like ` [ require: ['_id' , 'title', 'user', 'user.name' , ' user.age'] ` .
Yes. I updated my answer and added an example json scheme to it.
1

How about using assertJsonCount() to make sure you have the expected number of keys?

I have a DataTests class that contains a public static function that returns an array with the expected keys from my endpoint. If it returns more fields or less fields the count doen't match and the assertion fails.

DataTests.php

public static function arrayStructure(): array {
        return [
            //keys
        ];
    }

MyTest.php

public function test_array_structure() {
    $this->withHeaders($headers)->post(), [])
        ->assertJsonStructure(DataTests::arrayStructure())
        ->assertJsonCount(count(DataTests::arrayStructure(), COUNT_RECURSIVE));
    }

That way if I add a new column to my array in the future my tests will fail if I don't add the new value to my arrayStructure().

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.