Вопрос:
Каковы преимущества использования Factory Boy в следующей ситуации? Я действительно не понимаю, почему я не должен просто доставлять свои собственные пользовательские объекты. Если я ошибаюсь, объясните, почему.
Я использую Factory Boy для создания пользовательских экземпляров во время тестов, который динамически создает объект UserProfile (стандартный рецепт от Factory_Boy документация).
Класс Data создает данные, которые будут доставлены в формы во время публикации (другие методы, которые я использую, доставляют данные для методов self.client.post, которые входят в систему, регистрируют и активируют пользователей. Если я что-то не упустил, я бы чтобы создать отдельный подкласс DjangoModelFactory для каждой ситуации, чтобы использовать ClassName.attributes(), где требования к данным различаются.Другая причина, по которой я пошел в этом направлении, заключается в том, что UserProfile имеет внешний ключ пользователя, поэтому я не смог вызвать UserProfileFactory .attributes() напрямую, только UserFactory.attributes() Почему бы просто не сделать свой собственный, как я?
#Factories.py
IMAGE_PATH = os.path.join(os.path.dirname(__file__),
'../../test_files/test_images/image.jpeg')
class UserProfileFactory(DjangoModelFactory):
FACTORY_FOR = UserProfile
user = factory.SubFactory('portal.factories.UserFactory', profile=None)
first_name = factory.Sequence(lambda n: "Joe_%d" % n)
last_name = factory.Sequence(lambda n: "Schmoe_%d" % n)
nickname = factory.Sequence(lambda n: "JoeBlow_%d" % n)
profile_image = factory.LazyAttribute(lambda t: File(open(IMAGE_PATH)))
class UserFactory(DjangoModelFactory):
FACTORY_FOR = User
username = factory.Sequence(lambda n: "user_%d" % n)
password = make_password("password")
email = factory.Sequence(lambda n: "user_%[email protected]" % n)
profile = factory.RelatedFactory(UserProfileFactory, 'user')
@classmethod
def _generate(cls, create, attrs):
models.signals.post_save.disconnect(user_post_save, sender=User)
user = super(UserFactory, cls)._generate(create, attrs)
models.signals.post_save.connect(user_post_save, sender=User)
return user
class Data(object):
def __init__(self):
self.IMAGE_PATH = os.path.join(os.path.dirname(__file__),
'../../test_files/test_images/image.jpeg')
self.profile_image = File(open(IMAGE_PATH))
def get_profile_update(self, user):
return {'first_name': 'Jeff',
'last_name': 'Lebowski',
'nickname': 'The Dude',
'profile_image': self.profile_image,
'user': user.pk,}
def and_so_on(self):
continues...
Затем я использую такие данные в следующем контексте во время своих интеграционных тестов:
class PortalTestCase(TestCase):
"""Shortened and simplified"""
def test_edit_profile_post(self):
user = UserFactory.create()
login_bool = self.client.login(username=user.username,
password=self.data.get_password())
data = self.data.get_profile_update(user)
response = self.client.post(reverse(self.get_edit_profile()),
data=data,
follow=True)
success_url = 'http://testserver%s' % reverse(self.get_portal())
template_name = self.get_portal_template()
content_text_img = 'src="/' + user.get_profile().profile_image.url + '"'
self.assertRedirects(response, success_url)
self.assertTemplateUsed(response, template_name)
self.assertContains(response, content_text_img)