标签: factory-boy

是否将过多的参数传递给构造函数被认为是反模式?

我正在考虑使用factory_boy库进行API测试.文档中的一个例子是:

class UserFactory(factory.Factory):
    class Meta:
        model = base.User

    first_name = "John"
    last_name = "Doe"
Run Code Online (Sandbox Code Playgroud)

对于这项工作,我们需要的first_name,last_name等被作为参数传递__init__()的方法base.User() class.但是,如果您有许多参数,则会导致以下情况:

class User(object):

    GENDER_MALE = 'mr'
    GENDER_FEMALE = 'ms'

    def __init__(self, title=None, first_name=None, last_name=None, is_guest=None,
             company_name=None, mobile=None, landline=None, email=None, password=None,
             fax=None, wants_sms_notification=None, wants_email_notification=None,
             wants_newsletter=None, street_address=None):

        self. title = title
        self.first_name = first_name
        self.last_name = last_name
        self.company_name = company_name
        self.mobile = mobile
        self.landline = landline
        self.email = email
        self.password = password
        self.fax = fax
        self.is_guest = is_guest
        self.wants_sms_notification …
Run Code Online (Sandbox Code Playgroud)

python factory-boy

7
推荐指数
3
解决办法
8112
查看次数

工厂男孩子工厂传递对象而不是密钥

我正在使用带有 SQLAlchemy 的工厂男孩。

我正在尝试创建 Fact 对象,并且希望工厂男孩生成作为 Fact 的外键的 PatientDim 对象。但 Subfactory 不传递键,而是将整个对象传递给外键字段。

我怎样才能只通过 Subfactory 传递 PatientDim 密钥?

工厂.py

class FactFactory(SQLAlchemyModelFactory):
    class Meta:
        model = models.Fact
        sqlalchemy_session = common.Session

    patient_id = factory.SubFactory(PatientDimFactory)

class PatientDimFactory(SQLAlchemyModelFactory):
    class Meta:
        model = models.PatientDim
        sqlalchemy_session = common.Session
Run Code Online (Sandbox Code Playgroud)

模型.py

class Fact(TimeStampedModel):
    class Meta:
        db_table = 'fact'

    id = Column(Integer, primary_key=True)
    patient_id = Column('patient_id', Integer, ForeignKey(PatientDim.__table__.c.id), nullable=False)
    patient = relationship(PatientDim, foreign_keys='Fact.patient_id' )

Base = declarative_base()
class PatientDim(TimestampMixin, Base):
    __tablename__ = 'patient_dim'

    id = Column('id', Integer, primary_key=True)
Run Code Online (Sandbox Code Playgroud)

python sqlalchemy factory-boy

7
推荐指数
1
解决办法
1962
查看次数

Python:Factory Boy 生成对象创建时指定长度的列表

我正在尝试使用 Factoryboy 在创建时指定长度的对象中创建一个列表。

我可以创建列表,但是由于提供的长度/大小的惰性性质,每次尝试创建具有指定长度的列表都会导致问题。

这是我到目前为止所拥有的:

class FooFactory(factory.Factory):

    class Meta:
        model = command.Foo

    foo_uuid = factory.Faker("uuid4")
    bars = factory.List([
        factory.LazyAttribute(lambda o: BarFactory()
        for _ in range(3))
    ])
Run Code Online (Sandbox Code Playgroud)

这将创建一个包含 3 个随机条的列表。我尝试过使用 Params 和排除的组合,但由于 range 需要一个 Int,并且 int 直到稍后才会延迟加载,因此会导致错误。

我想要类似于如何使用 post_ Generation 生成一对多关系的东西,即。

foo = FooFactory(number_of_bars=5)
Run Code Online (Sandbox Code Playgroud)

有人有这样的运气吗?

python unit-testing factory-boy

7
推荐指数
1
解决办法
2492
查看次数

在Factory Boy的对象工厂中重写模型@property

我想找到一种方法来正确测试我的代码与Factory Boy.

有一个模型,像这样:

from django.db import models

class MyModel(models.Model):
    param1 = <some field>
    param1 = <some field>
    param1 = <some field>

    @property
    def is_smth(self):
        <some complicated code that returns boolean>
Run Code Online (Sandbox Code Playgroud)

这个型号有一个工厂:

import factory

class MyModelFactory(factory.DjangoModelFactory):
    param1 = <some value>
    param2 = <some value>
    param3 = <some value>

    # And here i need to "rewrite" property of the model
    # so that it would always return true
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助我吗?我没有在工厂男孩的文档中找到关于这个的提及,我尝试的各种变体似乎不起作用.

python django unit-testing factory-boy

6
推荐指数
1
解决办法
976
查看次数

如何为Factory Boy指定数据库?

FactoryBoy似乎总是在默认数据库中创建实例.但我有以下问题.

cpses = CanonPerson.objects.filter(persons__vpd=6,
                                   persons__country="United States").using("global")
Run Code Online (Sandbox Code Playgroud)

代码指向global数据库.我还没有找到在工厂中指定数据库的方法:

class CanonPersonFactory(django_factory.DjangoModelFactory):
    class Meta:
        model = CanonPerson
        django_get_or_create = ('name_first', 'p_id')
    p_id = 1
    name_first = factory.Sequence(lambda n: "name_first #%s" % n)

    @factory.post_generation
    def persons(self, create, extracted, **kwargs):
        if not create:
            # Simple build, do nothing.
            return

        if extracted:
            # A list of groups were passed in, use them
            for person in extracted:
                self.persons.add(person)
Run Code Online (Sandbox Code Playgroud)

python django factory-boy

6
推荐指数
1
解决办法
511
查看次数

为什么对象主键在Django的测试之间递增?

class MyClassTest(TestCase):
    def setUp(self):
        Someclass.objects.create()

    def test_first_test(self):
        # Here, Someclass.objects.all()[0].pk -> returns 1

    def test_second_test(self):
       # Here, Someclass.objects.all()[0].pk -> returns 2 !!! (bad !)
Run Code Online (Sandbox Code Playgroud)

使用SetUp()方法,应该清除数据并在每次测试之间重新创建.那么,为什么id从一个测试增加到另一个测试呢?这对我来说并不明显.

这样我就无法根据id进行测试(因为它们取决于其他测试).这就是为什么我总是希望得到1结果.

请注意,我对数据本身没有任何问题,旧数据可以从一个测试清除到另一个测试.问题只是ids.

我在这里读到django对象id在单元测试之间递增,问题与​​数据库有关,而不是与Django有关,但Django有没有改变它的技巧?

python django unit-testing factory-boy

6
推荐指数
2
解决办法
1930
查看次数

Scala或Java相当于Ruby factory_girl或Python factory_boy(用于单元测试的便捷工厂模式)

当我在动态类型的Ruby或Python中编写单元测试时,我分别使用库factory_girlfactory_boy,以便方便地生成测试对象.它们提供了直接对象实例化的便捷功能,例如:

  • 工厂继承和覆盖
  • 字段默认值和覆盖
  • 懒惰计算的依赖/派生字段
  • 构建依赖/相关的其他对象
  • 隐式惰性字段依赖性解析

在静态类型的Java或Scala中编写单元测试时,我可以使用哪些库/框架来实现具有类似优点的类似效果?

提前致谢!

我在这里发现了一个类似的StackOverflow问题,但不幸的是,最好的答案是(释义),"没有直接的等价,因为那将毫无意义".

java unit-testing scala factory-boy factory-bot

6
推荐指数
1
解决办法
2422
查看次数

如何使用相同的外键为 Django 模型创建工厂男孩工厂

当两个或多个模型有一个共同的外键时,我的工厂不断遇到问题,而每个模型都创建了自己的对象,而它们应该具有相同的对象。

为了说明问题,这里是一个简化的模型结构:

class Language (models.Model):
    code = models.CharField(max_length=3, unique=True)


class Audio(models.Model):
    language = models.ForeignKey(Language)
    soundfile = models.FileField()


class Subtitles(models.Model):
    language = models.ForeignKey(Language)
    text = models.TextField()


class Recording(models.Model):
    audio = models.ForeignKey(Audio)
    subtitles = models.ForeignKey(Subtitles)
Run Code Online (Sandbox Code Playgroud)

所以 aRecording具有AudioSubtitles,并且两者都有一个Language对于每种语言代码都是唯一的。

这是这种结构的工厂。

class LanguageFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = Language


class AudioFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = Audio

    language = factory.SubFactory(LanguageFactory, code='en1')


class SubtitlesFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = Subtitles

    language = factory.SubFactory(LanguageFactory, code='en1')


class RecordingFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = Recording …
Run Code Online (Sandbox Code Playgroud)

django factory-boy

6
推荐指数
1
解决办法
3925
查看次数

使用工厂男孩时如何覆盖模型保存功能?

我正在使用Factory Boy来测试Django项目,并且在测试我已经覆盖了save方法的模型时遇到了一个问题.

该模型:

class Profile(models.Model):

    active = models.BooleanField()
    user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE,
                             related_name='profiles')
    department = models.ForeignKey(Department, null=True, blank=True)
    category_at_start = models.ForeignKey(Category)
    role = models.ForeignKey(Role)
    series = models.ForeignKey(Series, null=True, blank=True)
    status = models.ForeignKey('Status', Status)

    def save(self, *args, **kwargs):
        super(Profile, self).save(*args, **kwargs)
        active_roles = []
        active_status = []
        for profile in Profile.objects.filter(user=self.user):
            if profile.active:
                active_roles.append(profile.role.code)
                active_status.append(profile.status.name)
        self.user.current_role = '/'.join(set(active_roles))
        if 'Training' in active_status:
            self.user.current_status = 'Training'
        elif 'Certified' in active_status:
            self.user.current_status = 'Certified'
        else:
            self.user.current_status = '/'.join(set(active_status))
        self.user.save()
        super(Profile, self).save(*args, …
Run Code Online (Sandbox Code Playgroud)

python testing django factory-boy

6
推荐指数
1
解决办法
801
查看次数

与 Factory Boy 的一对多关系

我的 SQLAlchemy 模型中有多对一关系。一份报告有许多示例(为简洁起见,进行了简化):

class Sample(db.Model, CRUDMixin):
    sample_id = Column(Integer, primary_key=True)
    report_id = Column(Integer, ForeignKey('report.report_id', ondelete='CASCADE'), index=True, nullable=False)
    report = relationship('Report', back_populates='samples')

class Report(db.Model, CRUDMixin):
    report_id = Column(Integer, primary_key=True)
    samples = relationship('Sample', back_populates='report')
Run Code Online (Sandbox Code Playgroud)

现在,在我的测试中,我希望能够生成一个Sample或多个实例Report,并填充缺失的关系。

class ReportFactory(BaseFactory):
    class Meta:
        model = models.Report
    report_id = Faker('pyint')
    samples = RelatedFactoryList('tests.factories.SampleFactory', size=3)

class SampleFactory(BaseFactory):
    class Meta:
        model = models.Sample
    sample_id = Faker('pyint')
    report = SubFactory(ReportFactory)
Run Code Online (Sandbox Code Playgroud)

当我去创建它们的实例时,工厂陷入无限循环:

RecursionError: maximum recursion depth exceeded in comparison
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试使用SelfAttributes 来停止无限循环,我最终会得到一个没有任何样本的报告:

RecursionError: maximum recursion depth …
Run Code Online (Sandbox Code Playgroud)

python sqlalchemy factory-boy

6
推荐指数
1
解决办法
2425
查看次数