diff --git a/src/fastapi_toolsets/fixtures/utils.py b/src/fastapi_toolsets/fixtures/utils.py index a9a4154..7c2acfb 100644 --- a/src/fastapi_toolsets/fixtures/utils.py +++ b/src/fastapi_toolsets/fixtures/utils.py @@ -29,9 +29,14 @@ def get_obj_by_attr( The first model instance where the attribute matches the given value. Raises: - StopIteration: If no matching object is found. + StopIteration: If no matching object is found in the fixture group. """ - return next(obj for obj in fixtures() if getattr(obj, attr_name) == value) + try: + return next(obj for obj in fixtures() if getattr(obj, attr_name) == value) + except StopIteration: + raise StopIteration( + f"No object with {attr_name}={value} found in fixture '{getattr(fixtures, '__name__', repr(fixtures))}'" + ) from None async def load_fixtures( diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 6e0dcea..8e465b1 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -744,8 +744,11 @@ class TestGetObjByAttr: assert user.username == "alice" def test_no_match_raises_stop_iteration(self): - """Raises StopIteration when no object matches.""" - with pytest.raises(StopIteration): + """Raises StopIteration with contextual message when no object matches.""" + with pytest.raises( + StopIteration, + match="No object with name=nonexistent found in fixture 'roles'", + ): get_obj_by_attr(self.roles, "name", "nonexistent") def test_no_match_on_wrong_value_type(self):