Reputation: 870
I use Phpunit in Laravel and my Api has multiple acceptable responses. I have problem in 2 case:
1- response structure can be one of these two:
$response->assertJsonStructure(['cities'=>[]]);
or
$response->assertJsonStructure(['cities'=>[['id','name']]])
2- response status can be 200 or 302
$response->assertStatus(200);
or
$response->assertStatus(302);
But I can't find any method to "OR" these two conditions.
I'm looking for something like this:
$response->assertOr(
$response->assertStatus(200),
$response->assertStatus(302)
);
Upvotes: 4
Views: 3680
Reputation: 131
I add this to my base TestCase
class:
/**
* Assert that at least one of the `callable`s pass (short-circuiting)
* @param array<callable> $callables
* @return void
*/
public function assertOr(array $callables, int $minimum = 1): void {
$this->assertGreaterThanOrEqual(1, $minimum);
$passCount = 0;
foreach ($callables as $callable) {
$passes = true;
try {
$callable();
} catch (ExpectationFailedException $e) {
$passes = false;
}
$passCount += (int) $passes;
if ($passCount >= $minimum) {
break;
}
}
$this->assertGreaterThanOrEqual($minimum, $passCount);
}
Upvotes: 0
Reputation: 141
for 2º case you can use like
if($response->getStatusCode() == 410) {
$response->assertStatus(410);
} else {
$response->assertStatus(200);
}
Upvotes: 1
Reputation: 3572
for #1 If you think the value could be empty, just match the key with assertArrayHasKey()
$response->assertArrayHasKey('cities', $response->getContent());
for #2 You can use assertContains()
Like
$response->assertContains($response->getStatusCode(), array(200,302));
Here you can find about more. https://phpunit.readthedocs.io/en/7.4/assertions.html#assertcontains
Upvotes: 8