【问题标题】:Django - getting user objects in testsDjango - 在测试中获取用户对象
【发布时间】:2012-10-23 16:19:06
【问题描述】:

我有一个这样的models.py:

from django.db import models
from django.contrib.auth.models import User


# everything has a colour...
class Colour(models.Model):
    colour = models.CharField(max_length=100)

    def __unicode__(self):
        return self.colour


# a thing can have a colour...
class Thing(models.Model):
    name = models.CharField(max_length=155)
    colour = models.ForeignKey(Colour)
    description = models.CharField(max_length=255)

    def __unicode__(self):
        return self.name


# a user can save his choices
class UserLikes(models.Model):
    user = models.ForeignKey(User)
    colour = models.ForeignKey(Colour)
    thing = models.ForeignKey(Thing)

    class Meta:
        verbose_name_plural = "User Likes"

    def __unicode__(self):
        return '%d - %s' % (self.pk, self.user)

在我看来:

def ThingPicker(request):
    if request.method == 'POST':
        form = ThingForm(request.POST)
        if form.is_valid():
            colour = form.cleaned_data['colour']
            thing = form.cleaned_data['thing']
            likes = UserLikes(user=request.user, colour=colour, thing=thing)
            likes.save()
            return HttpResponseRedirect('/profile/')
        else:
            return render_to_response('thing_picker.html', {
                'form': form,
            }, RequestContext(request))
    else:
        form = ThingForm()
        return render_to_response('thing_picker.html', {
            'form': form,
        }, RequestContext(request))

在我的 tests.py 中,我想做这样的事情(EDITED):

class ViewTests(TestCase):
    def setUp(self):
        self.client = Client()      

    def test_thingpicker(self):
        User.objects.create_superuser('foo', 'myemail@test.com', 'bar')
        self.client.login(username='foo', password='bar') # request.user is now user foo

        response = self.client.post('/colours/things/', {'colour': 1, 'thing': 2})
        userlike = UserLikes.objects.get(pk=1)
        self.assertEqual(userlike.colour_id, 1)

我收到一个错误:

DoesNotExist: UserLikes matching query does not exist.

如果我尝试在 shell 中使用测试客户端:

>>>  c = Client()
>>>  user1 = User.objects.create_superuser('foo', 'myemail@test.com', 'bar')
>>>  c.login(username='foo', password='bar')
>>>  c.post('/colours/things/', {'user': user1, 'colour': 1, 'thing': 2})
>>>  userlike = UserLikes.objects.get(pk=1)
>>>  userlike.colour_id
1L

我得到了预期的结果。

【问题讨论】:

    标签: django unit-testing testing


    【解决方案1】:

    您的视图代码有些奇怪(意外剪切和粘贴?),但来自以下代码行:

    likes = UserLikes(user=request.user, colour=colour, thing=thing)
    

    我猜你正在获取当前登录的用户。要从测试用例中正确获取新创建的超级用户,您应该这样做:

    def test_thingpicker(self):
        user1 = User.objects.create_user('foo', 'myemail@test.com', 'bar')
    
        self.client.login(username='foo', password='bar') # request.user is now user foo
    
        response = self.client.post('/colours/things/', {'colour': 1, 'thing': 2})
        userlike = UserLikes.objects.get(user=user1, color=1, thing=2)
    

    此外,您应该注意 request.user 可能是 AnonymousUser(请参阅https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.AnonymousUser),因此您应该在创建 UserLikes 之前检查用户是否已登录。

    您可以通过使用 @login_required 装饰器 (https://docs.djangoproject.com/en/dev/topics/auth/#the-login-required-decorator) 或手动检查 request.user.is_authenticated() (https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.AbstractBaseUser.is_anonymous) 来实现。

    为什么没有创建 UserLikes

    从外观上看:

    colour = form.cleaned_data['colour']
    thing = form.cleaned_data['thing']
    likes = UserLikes(user=request.user, colour=colour, thing=thing)
    

    请注意,UserLikes 的模型定义将 ForeignKey 用于 Color 和 Thing。我猜测表单中的colourthingIntegerField,因此您需要检索实际的Color 和Thing 对象。

    color = Colour.objects.get(pk=form.cleaned_data['colour'])
    thing = Thing.objects.get(pk=form.cleaned_data['thing'])
    likes = UserLikes(user=request.user, colour=colour, thing=thing)
    

    当然,您需要确保之前已经创建了 Color 和 Thing 对象。

    【讨论】:

    • 谢谢。所以我更改了测试代码,以便针对登录用户进行测试。我可以用 shell 中的 Client 模拟这个,但测试仍然失败,说:DoesNotExist: UserLikes matching query does not exist.
    • 我相信您新创建的 UserLikes 的 PK 不是 1。您可以为您的 View 编辑原始帖子以显示正确的代码吗?当前有一行断言与 View 代码混合。我已经编辑了test_thingpicker 的最后一行代码,以获取您刚刚创建的类似用户的对象。
    • 哦,是的 - 看到错字了。不知道为什么 pk 在新创建的数据库上不会是 1?当然,在全新的数据库上,pk 将永远是 1,不是吗?
    • 而且你的代码调整对我还是不起作用。就好像从未创建过 UserLikes 对象。
    • 查看我的更新答案。您还应该在检查 PK(例如UserLikes.objects.count() == 1)之前断言已创建 UserLikes 对象,以确保已成功创建 UserLikes。
    【解决方案2】:

    最终生效的代码:

    tests.py:

    class ViewTests(TestCase):
        """
        Run before each test in class
        """
        def setUp(self):
            self.client = Client()
            self.user = User.objects.create_superuser(
                'foo',
                'myemail@test.com',
                'pass'
            )
            self.colour = Colour.objects.create(colour='Green')
            self.thing = Thing.objects.create(
                name='Leaf',
                colour=self.colour,
                description='leafy'
            )
            self.logged_in = self.client.login(
                username='foo',
                password='pass'
            )
    
        """
        Test whether user can login and post choice
        to db and then check if data can be retreived.
        """
        def test_thingpicker(self):
            # check new User object created
            self.assertEqual(User.objects.count(), 1)
            # check use is logged in
            self.assertEqual(self.logged_in, True)  # check login success
    
            # post some data
            response = self.client.post(
                '/colours/things/', {
                'colour': self.colour.pk,
                'thing': self.thing.pk
                })
            self.assertEqual(response.status_code, 200)
    
            # check object
            self.assertEqual(UserLikes.objects.count(), 1)
            userlikes = UserLikes.objects.get(
                user=self.user,
                colour_id=self.colour.pk,
                thing=self.thing.pk
            )
            self.assertEqual(userlikes.colour_id, self.colour.pk)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-25
      • 2012-05-03
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      相关资源
      最近更新 更多