Skip to content

Instantly share code, notes, and snippets.

@oli-laban
Created November 7, 2025 18:05
Show Gist options
  • Select an option

  • Save oli-laban/5ebbae1c382595ba94d7cbcaf42eee98 to your computer and use it in GitHub Desktop.

Select an option

Save oli-laban/5ebbae1c382595ba94d7cbcaf42eee98 to your computer and use it in GitHub Desktop.
Custom Pest assertion to assert that a model has all the provided relations loaded, using the same dot syntax as with() and load()
<?php
expect()->extend('toHaveLoadedRelations', function (array $relations) {
$model = $this->value;
$tested = [];
expect($model)->toBeInstanceOf(Model::class, 'toHaveLoadedRelations expects a Model instance.');
assert($model instanceof Model);
foreach ($relations as $relation) {
$parts = explode('.', $relation);
$currentModel = $model;
foreach ($parts as $index => $part) {
$testing = implode('.', array_slice($parts, 0, $index + 1));
if (! in_array($testing, $tested, true)) {
expect($currentModel->relationLoaded($part))->toBeTrue("Expected relation $testing to be loaded.");
$tested[] = $testing;
}
if ($index < count($parts) - 1) {
$nextRelation = $currentModel->getRelation($part);
if ($nextRelation instanceof Collection && $nextRelation->isEmpty()) {
note("The relation $testing is empty. Skipping to the next relation.");
continue 2;
}
$currentModel = $nextRelation instanceof Collection
? $nextRelation->first()
: $nextRelation;
}
}
}
})
@oli-laban
Copy link
Author

Example:

Post::query()
    ->with([
        'images',
        'comments.replies',
    ])
    ->findOrFail(123);

// Assert relations loaded in test
expect($post)->toHaveLoadedRelations([
        'images',
        'comments.replies',
])

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