我刚从Django开始,我想也许有人能教我一个简单的测试,我写的应该通过,但显然没有。嗯,我说应该,但作为Django的新手,我想我的知识不足是它失败的原因。
我用另一个模型和一对一关系扩展了django用户模型,如文档中所建议的那样,将一个字段添加到模型中。这个模型,即userstep,只包含一个从零开始的整数。我决定扩展管理器来实现一个名为setuserstep的方法,该方法在满足条件时将步骤设置为一个新值。
模型.py
class UserStepManager(models.Manager):
def setUserStep(self, user, conditional_step, step):
if user.userstep.step == conditional_step:
user.userstep.step = step
user.userstep.save()
class UserStep(models.Model):
"""This model holds the user step count"""
user = models.OneToOneField(User)
step = models.IntegerField(default=0)
# we set the custom manager
objects = UserStepManager()
然后当用户注册时,将创建一个新的userstep对象。
模型.py
@receiver(user_signed_up)
def complete_social_signup(sender, **kwargs):
"""We start step to 0"""
user = kwargs.pop('user')
us = UserStep(user=user)
us.save()
我在一个视图中使用管理器中定义的
setUserStep
方法,当用户请求/phase1/step1/
URL时,将调用该方法因此,如果当前步进为零,则将其设置为1。就这么简单。视图.py
@login_required
def step1(request):
context_dict = {}
UserStep.objects.setUserStep(request.user, 0, 1)
return render(request, 'phase1/step1.html', context_dict)
我通过注册和调用这个视图手工测试了这个行为,一切都按预期工作当我检查数据库时,
user.userstep.step
设置为1。然后,作为一个好孩子,我决定开始写一些测试(我还没有到先写测试的地步,我应该在那之前写测试来测试我的测试:P)。
测试.py
class MyTests(TestCase):
def setUp(self):
self.test_user = User.objects.create_user(username="test",
email="test@test.com",
password="test")
# Mock user_signed_up signal.
us = UserStep(user=self.test_user)
us.save()
self.c = Client()
def test_step_gets_incremented(self):
self.c.login(username="test", password="test")
response = self.c.get('/phase1/step1/')
# user is logged in, the test should pass
self.assertEqual(response.status_code, 200)
current_user_step = self.test_user.userstep.step
# Test doesn't pass. WHY ME
self.assertEqual(current_user_step, 1)
和BOOM
AssertionError: 0 != 1
我甚至在我的view方法中做了一个简单的print,它会被调用。
谢谢!
最佳答案
由于将用户更改为另一个用户实例,因此必须从数据库中重新加载test_user
这意味着如果:
u1 = User.objects.get(id = 1)
u2 = User.objects.get(id = 1)
对
u1
的更改(即使已保存)不会镜像到u2
。所以在请求之后,您必须再次从数据库获取用户。