Dar*_*ech 4 django unit-testing django-models django-testing django-tests
我刚刚开始在Mock不接触数据库的情况下测试 Django 应用程序。我可以在测试中成功模拟我的模型对象,但我对如何处理涉及对象的模型方法有点困惑。
作为一个例子,我的 models.py 中有这个:
class Skill(models.Model):
title = models.CharField(max_length=255)
category = models.ForeignKey(
SkillCategory, default=None, null=True, blank=True
)
def __unicode__(self):
return self.title
class UserProfile(models.Model):
user = models.OneToOneField(User)
skill = models.ManyToManyField(Skill, default=None)
avatar = models.URLField(
max_length=400, default=None, null=True, blank=True
)
def __unicode__(self):
return self.user.username
def update_skills(self, cleaned_skills):
for s in cleaned_skills:
skill, created = Skill.objects.get_or_create(title=s)
self.skill.add(skill)
Run Code Online (Sandbox Code Playgroud)
到目前为止,在我的重构测试中我已经这样做了:
class ProfileTestCase(unittest.TestCase):
def setUp(self):
# mock user
self.user = mock.Mock(spec=User)
self.user.username = "john"
self.user.email = "johndoe@hotmail.com"
self.user.password = "pass"
# mock profile
self.userprofile = mock.Mock(spec=UserProfile)
self.userprofile.user = self.user
# mock skill category
self.skill_category = mock.Mock(spec=SkillCategory)
self.skill_category.title = "foo"
# mock skill
self.skill = mock.Mock(spec=Skill)
self.skill.title = "ninja"
self.skill.category = self.skill_category
def test_skillcategory_created(self):
self.assertEqual(self.skill.category.title, 'foo')
def test_skill_created(self):
self.assertEqual(self.skill.title, 'ninja')
...
# and so on
Run Code Online (Sandbox Code Playgroud)
在我使用数据库的旧测试中,我用这个来测试我的模型方法:
...
def test_update_skills(self):
cleaned_skills = ['mysql', 'unix']
self.userprofile.update_skills(cleaned_skills)
skills = self.userprofile.skill.values_list('title', flat=True)
self.assertTrue('mysql' in skills)
Run Code Online (Sandbox Code Playgroud)
我正在绞尽脑汁思考如何重构这一行:
self.userprofile.update_skills(cleaned_skills)
Run Code Online (Sandbox Code Playgroud)
从中获利Mock。
您可以模拟该get_or_create()方法以及skill关系,以便在不访问数据库的情况下运行测试。
def test_update_skills(self):
def mock_get_or_create(title):
return title, True
mock_skill = set()
with mock.patch('analytics.models.Skill.objects.get_or_create',
mock_get_or_create), \
mock.patch.object(UserProfile, 'skill', mock_skill):
userprofile = UserProfile()
cleaned_skills = ['mysql', 'unix']
userprofile.update_skills(cleaned_skills)
self.assertEqual({'mysql', 'unix'}, mock_skill)
Run Code Online (Sandbox Code Playgroud)
我正在帮助完成一个django_mock_queries项目,该项目有助于提供一系列 Django 查询集功能,而无需访问数据库。它使我们的许多测试速度更快。
| 归档时间: |
|
| 查看次数: |
12377 次 |
| 最近记录: |