Skip to content

Commit

Permalink
Factory fixture should apply parametrizations
Browse files Browse the repository at this point in the history
  • Loading branch information
youtux committed Jan 12, 2025
1 parent 29c01c5 commit 9ddedcb
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 12 deletions.
20 changes: 18 additions & 2 deletions pytest_factoryboy/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,18 @@ def generate_fixtures(
),
)

deps = get_deps(factory_class, model_name=model_name)
if factory_name not in caller_locals.value:
yield (
factory_name,
create_fixture_with_related(
name=factory_name,
function=functools.partial(factory_fixture, factory_class=factory_class),
fixtures=deps,
# TODO: related too?
),
)

deps = get_deps(factory_class, model_name=model_name)
yield (
model_name,
create_fixture_with_related(
Expand Down Expand Up @@ -345,6 +347,7 @@ def model_fixture(request: SubRequest, factory_name: str) -> Any:
fixture_name = request.fixturename
prefix = "".join((fixture_name, SEPARATOR))

# TODO: This should be a dependency of the current fixture (i.e. use `usefixtures`)
factory_class: FactoryType = request.getfixturevalue(factory_name)

# Create model fixture instance
Expand Down Expand Up @@ -478,7 +481,20 @@ def deferred_impl(request: SubRequest) -> Any:

def factory_fixture(request: SubRequest, factory_class: F) -> F:
"""Factory fixture implementation."""
return factory_class
fixture_name = request.fixturename
# TODO: Not good to check the fixture name, we should know what to expect (via args?)
assert fixture_name.endswith("_factory")
fixture_name = fixture_name[: -len("_factory")]
prefix = "".join((fixture_name, SEPARATOR))

# TODO: copy-paste from model_fixture; refactor
kwargs = {}
for key in factory_class._meta.pre_declarations:
argname = "".join((prefix, key))
if argname in request._fixturedef.argnames:
kwargs[key] = evaluate(request, request.getfixturevalue(argname))

return type(f"{factory_class.__name__}Fixture", (factory_class,), kwargs)


def attr_fixture(request: SubRequest, value: T) -> T:
Expand Down
11 changes: 1 addition & 10 deletions tests/test_factory_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class Meta:

def test_factory(book_factory) -> None:
"""Test model factory fixture."""
assert book_factory == BookFactory
assert issubclass(book_factory, BookFactory)


def test_model(book: Book):
Expand Down Expand Up @@ -213,12 +213,3 @@ def test_override_subfactory_with_lazy_fixture(self, another_book: Book):
"""
assert another_book.author.name == "Another Author"


class TestDeferredEvaluation:
@pytest.mark.parametrize("book__name", ["bar"])
def test_book_initialise_later(self, book_factory, book):
assert book.name == "bar"

book_f = book_factory()
assert book_f.name == "bar"
30 changes: 30 additions & 0 deletions tests/test_foo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# TODO: Improve tests
# TODO: Change test module

from dataclasses import dataclass

import factory
import pytest

from pytest_factoryboy import register


@dataclass
class Book:
name: str


@register
class BookFactory(factory.Factory):
class Meta:
model = Book

name = "foo"


@pytest.mark.parametrize("book__name", ["bar"])
def test_book_initialise_later(book_factory, book__name, book):
assert book.name == "bar"

book_f = book_factory()
assert book_f.name == "bar"

0 comments on commit 9ddedcb

Please sign in to comment.