For a Laravel Test of my Product API I am trying to check if the right number of prices are listed for all products. The API returns Json and the prices are items in the products.*.prices arrays.
I am new to Laravel Test.
How do I loop through all the products and check their prices?
$response = $this->getJson('/api/product/');
$json_array = $response->json();
$test_passed = true;
for ($i = 0; $i < count($json_array); $i++) {
//for simplification I check here if all the products have 2 prices
$test_passed = $response->assertJsonCount(2, "product.$i.prices");
}
//check if all the test passed
$this->assertTrue($passed_test);
This works but it runs out of memory really fast. What am I doing wrong?
UPDATE:
I found in the Laravel API that AssertableJson has and ->each() method. I was trying to play around with this to make something like
$response->assertJson(fn (AssertableJson $json) =>
$json->each(fn (AssertableJson $json) =>
//2 will be dynamic in the final implementation.
$json->has('prices', 2)
)
);
This doesn’t work, Apperently… I can’t figure out how this ->each() works and there are no examples online to be found. All I can find are the Laravel docs, yet they give no example with nested arrarys.
2
Answers
Since you should be wiping your database clean for every test to start with a clean slate, I think the steps to take are
Product
models with an arbitrary amount ofPrice
models associated with themProduct
models as we specified in step 1.Product
has as manyPrice
models associated with them as we specified in step 1.Here notice I’m using the
key
value of the array in the foreach. This is not possible with theAssertableJson
syntax because the Closure does not accept a second parameter (unlike theCollection
‘seach
method where I could use the key if I wanted to with$collection->each(function ($item, $key) { ... });
.The AssertableJson API is a bit limited so you cannot really use it for this test, unless you make a single type of product.
Another test you can create and that is sort of important for json apis is a test against the returned json structure. In your case it would look like this
I tested this last one against the json you posted (jsonblob.com/1087309750307405824) and it passes.
Based on your JSON that you posted here: https://jsonblob.com/1087309750307405824
some minor change can fix your problem
If your code runs out of memory, it could be that you get all products in your database and product JSON size is too large or could be memory limitation in your system.
For checking php memory usage, you can use memory_get_usage function in your "for loop"