Custom creation of related SubFactory using factory_boy

  factory-boy, faker, python, python-3.x, testing

Assume I have the following classes:

@dataclass
class Image:
    array: np.ndarray


@dataclass
class Label:
    array: np.ndarray


@dataclass
class Sample:
    image: Image
    label: Label

with the following factory_boy factories:

class ImageFactory(factory.Factory):
    class Meta:
        model = Image

    class Params:
        shape = (64, 64)

    array = factory.LazyAttribute(lambda o: np.random.random(o.shape))


class LabelFactory(factory.Factory):
    class Meta:
        model = Label

    class Params:
        shape = (64, 64)

    array = factory.LazyAttribute(lambda o: np.random.randint(0, 2, o.shape))

Now, the SampleFactory is not as straightforward. I need to create an Image and Label that are related. Since this:


class SampleFactory(factory.Factory):
    class Meta:
        model = Sample

    image = factory.SubFactory(ImageFactory)
    label = factory.SubFactory(LabelFactory)

generates independent Image and Label classes. Assume I have a random_sample function that generates the arrays used by classes Image and Label. How could I use this in the SampleFactory? Furthermore, assume now the SampleFactory has a Param shape, used in the random_sample i.e. random_sample(shape) how would the implementation on the SampleFactory be?

Update

Seems this may be used, not sure if it’s the best way:

class SampleFactory(factory.Factory):
    class Meta:
        model = Sample

    class Params:
        shape = (32, 32)

    @classmethod
    def _create(cls, model_class, *args, **kwargs):
        params = {k: v.value for k, v in cls._meta.parameters.items()}
        image_array, label_array = random_sample(**params)
        image = Image(array=image_array)
        label = Label(array=label_array)

        return Sample(image=image, label=label)

Source: Python Questions

LEAVE A COMMENT