【发布时间】:2019-12-22 02:50:18
【问题描述】:
我正在为我正在开发的网站编写测试,并使用 factoryboyFactory 对象来表示模型。
但是,我遇到了一些让我有些困惑的行为,我想知道这里是否有人会这么好心地向我解释一下
我正在运行一个包含以下模型的测试:
STATUS = (
('CALCULATING'),
('PENDING'),
('BUSY'),
('SUCCESS'),
('FAILED')
)
class SchoolImport(models.Model):
date = models.DateTimeField(auto_now_add=True)
status = models.CharField(
verbose_name=_('status'), choices=STATUS,
max_length=50, default='CALCULATING'
)
为此我创建了以下工厂。如您所见,status 设置为其默认值,我发现这比随机选择的值更现实
class SchoolImportFactory(factory.DjangoModelFactory):
class Meta:
model = models.SchoolImport
status = 'CALCULATING'
school = factory.SubFactory(SchoolFactory)
@factory.lazy_attribute
def date(self):
return timezone.now() - datetime.timedelta(days=10)
您将在下面看到正在测试的函数的(简化)版本以及测试本身。 (我目前已注释掉笔记本电脑上的所有其他代码,因此您在下面看到的功能是准确的表示)
它的要点是该函数接收一个id 值,它将用于从数据库中获取一个SchoolImport 对象并更改其状态。该函数将在 celery 中运行,因此不返回任何内容。
当我通过调试器运行此测试时,我可以看到值已正确更改。但是,当测试运行其最终断言时,它会失败,因为 self.school_import.status 仍然等于 CALCULATING。
#app.utils.py
def process_template_objects(school_import_pk):
school_import = models.SchoolImport.objects.get(id=import_file_pk)
school_import.status = 'BUSY'
school_import.save()
#app.tests.test_utils.py
class Test_process_template_objects_function(TestCase):
def setUp(self):
self.school = SchoolFactory()
self.school_import = SchoolImportFactory(
school=self.school
)
def test_function_alters_school_import_status(self):
self.assertEqual(
self.school_import.status, 'CALCULATING'
)
utils.process_template_objects(self.school_import.id)
self.assertNotEqual(
self.school_import.status, 'CALCULATING'
)
当我通过调试器(在失败的断言之前有一个断点)运行此测试并运行SchoolImport.objects.get(id=self.school_import.id).status 时,它确实返回了正确的BUSY 值。
因此,尽管由 FactoryInstance 表示的对象正在正确更新,但更改不会反映在工厂实例本身中。
虽然我意识到我可能在这里做错了/遇到了预期的行为,但我想知道使用 factoryboy f 编写测试的人如何绕过这种行为,或者是否有一种方法可以“刷新” factoryboy 实例以反映模型实例的更改。
【问题讨论】:
-
我想知道是不是因为您在运行
models.SchoolImport.objects.get(id=import_file_pk)时创建了一个新的学校导入对象,如果您将学校导入对象本身传递给函数会怎样。像def process_template_objects(school_import): school_import.status = ‘BUSY’ school_import.save()这样的东西。 get 中的参数没有意义,您使用的是import_file_pk,但函数中没有定义。
标签: python django django-testing factory-boy