4

私はオープン ソースの django Web アプリに取り組んでおり、Factory Boy を使用していくつかのテスト用のモデルをセットアップすることを検討していますが、数時間ドキュメントを読んで例を見た後、敗北を受け入れる必要があると思いますとここで質問。

次のような Customer モデルがあります。

class Customer(models.Model):

    def save(self, *args, **kwargs):
        if not self.full_name:
            raise ValidationError('The full_name field is required')
        super(Customer, self).save(*args, **kwargs)


    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        related_name='customer',
        null=True
    )

    created = models.DateTimeField()
    created_in_billing_week = models.CharField(max_length=9)
    full_name = models.CharField(max_length=255)
    nickname = models.CharField(max_length=30)
    mobile = models.CharField(max_length=30, default='', blank=True)
    gocardless_current_mandate = models.OneToOneField(
        BillingGoCardlessMandate,
        on_delete=models.SET_NULL,
        related_name='in_use_for_customer',
        null=True,
    )

また、django.contrib.auth の標準の Django ユーザー モデルも使用しています。

これが私の工場コードです:

class UserFactory(DjangoModelFactory):

    class Meta:
        model = get_user_model()


class CustomerFactory(DjangoModelFactory):

    class Meta:
        model = models.Customer

    full_name = fake.name()
    nickname = factory.LazyAttribute(lambda obj: obj.full_name.split(' ')[0])

    created = factory.LazyFunction(timezone.now)
    created_in_billing_week = factory.LazyAttribute(lambda obj: str(get_billing_week(obj.created)))

    mobile = fake.phone_number()

    user = factory.SubFactory(UserFactory, username=nickname,
        email="{}@example.com".format(nickname))

私の場合、そのような顧客を生成できるようにしたい

CustomerFactory(fullname="Joe Bloggs")

そして、正しいユーザー名と電子メール アドレスを使用して、対応するユーザーを生成します。

現在、次のエラーが発生しています。

  AttributeError: The parameter full_name is unknown. Evaluated attributes are {'email': '<factory.declarations.LazyAttribute object at 0x111d999e8>@example.com'}, definitions are {'email': '<factory.declarations.LazyAttribute object at 0x111d999e8>@example.com', 'username': <DeclarationWrapper for <factory.declarations.LazyAttribute object at 0x111d999e8>>}.

これは、ユーザー ファクトリが作成される前に呼び出されない顧客の遅延属性に依存しているためだと思います。

上記のように、ファクトリを使用して Customer モデル インスタンスを作成し、対応するユーザーを作成できるようにするには、どうすればよいですか?

それだけの価値があるため、完全なモデルはgithub リポジトリでここに表示されます

4

1 に答える 1

5

その場合、最善の方法は、顧客の宣言から値を選択することです。

class CustomerFactory(DjangoModelFactory):

    class Meta:
        model = models.Customer

    full_name = factory.Faker('name')
    nickname = factory.LazyAttribute(lambda obj: obj.full_name.split(' ')[0])

    created = factory.LazyFunction(timezone.now)
    created_in_billing_week = factory.LazyAttribute(lambda obj: str(get_billing_week(obj.created)))

    mobile = factory.Faker('phone_number')

    user = factory.SubFactory(
        UserFactory,
        username=factory.SelfAttribute('..nickname'),
        email=factory.LazyAttribute(lambda u: "{}@example.com".format(u.username)))
    )

また、factory.Faker('field_name')各インスタンスのランダムな値を取得するために使用します。fullname = fake.name() クラス宣言の行は次と同等です。

DEFAULT_FULL_NAME = fake.name()

class CustomerFactory(DjangoModelFactory):
    full_name = DEFAULT_FULL_NAME

    class Meta:
        model = models.customer

一方factory.Faker('name')、次と同等です。

class CustomerFactory(DjangoModelFactory):
    full_name = factory.LazyFunction(fake.name)

    class Meta:
        model = models.customer

つまりfake.name()、このファクトリで構築された各モデルに異なる名前を付けます。

于 2016-09-17T16:56:57.943 に答える