Django登录测试会话问题

Django登录测试会话问题,django,session,testing,login,Django,Session,Testing,Login,下面是我试图用测试覆盖的两行代码: from django.contrib.auth import login from django.views.generic.edit import FormView from accounts.forms import UsernameLoginForm class LoginView(FormView): form_class = UsernameLoginForm success_url = '/' template_na

下面是我试图用测试覆盖的两行代码:

from django.contrib.auth import login
from django.views.generic.edit import FormView

from accounts.forms import UsernameLoginForm


class LoginView(FormView):
    form_class = UsernameLoginForm
    success_url = '/'
    template_name = 'login.html'

    def form_valid(self, form):
        login(self.request, form.get_user())
        return super(LoginView, self).form_valid(form)
这似乎是在功能上实现从django.contrib.auth.forms.AuthenticationForm扩展而来的登录表单的正确方法,但我必须自己从admin login视图中挖掘代码,因此需要进行适当的测试

让测试环境在会话中设置用户时遇到问题。RequestFactory没有会话支持,因此我尝试了以下方法:

from django.contrib.auth.models import User
from django.test import TestCase
from django.test.client import RequestFactory
import mox

from accounts.forms import UsernameLoginForm
from accounts.views import LoginView


class ViewTests(TestCase):

    def test_login(self):
        user = User.objects.create(username='userfoo')
        view = LoginView()
#        request = RequestFactory()
        view.request = self.client

        self.moxx = mox.Mox()
        form = self.moxx.CreateMock(UsernameLoginForm)
        form.get_user().AndReturn(user)

        self.moxx.ReplayAll()
        view.form_valid(form)
        self.moxx.VerifyAll()

        self.assertTrue(request.user)
这就是导致以下情况的错误:

  File "/home/renoc/.virtualenvs/alc/local/lib/python2.7/site-packages/django/contrib/auth/__init__.py", line 110, in login
    request.session.cycle_key()
  File "/home/renoc/.virtualenvs/alc/local/lib/python2.7/site-packages/django/contrib/sessions/backends/base.py", line 283, in cycle_key
    data = self._session_cache
AttributeError: 'SessionStore' object has no attribute '_session_cache'

self.client.request.session是易变的,如果我尝试在其上设置属性,它不会抛出错误,但在访问时也没有该属性。

经过大量工作后,我发现我可以将TestCase.client生成的会话附加到RequestFactory,并拥有一个可以更改的实例。下面是我为使我的测试有效而想到的

from django.contrib.auth.models import User
from django.test import TestCase
from django.test.client import RequestFactory
import mox

from accounts.forms import UsernameLoginForm
from accounts.views import LoginView


class ViewTests(TestCase):

    def setUp(self):
        self.moxx = mox.Mox()

    def tearDown(self):
        self.moxx.UnsetStubs()

    def test_login(self):
        user = User.objects.create(username='userfoo')
        user.backend = ''
        view = LoginView()
        request = RequestFactory()
        request.META = {}
        request.user = None
        request.session = self.client.session
        request.session.create()
        view.request = request

        form = self.moxx.CreateMock(UsernameLoginForm)
        form.get_user().AndReturn(user)

        self.moxx.ReplayAll()
        view.form_valid(form)
        self.moxx.VerifyAll()

        self.assertTrue(request.user)

我希望您仍然会提供建议,包括为什么我不应该首先做这样的事情。

经过大量工作,我发现我可以将TestCase.client生成的会话附加到RequestFactory,并拥有一个可以更改的实例。下面是我为使我的测试有效而想到的

from django.contrib.auth.models import User
from django.test import TestCase
from django.test.client import RequestFactory
import mox

from accounts.forms import UsernameLoginForm
from accounts.views import LoginView


class ViewTests(TestCase):

    def setUp(self):
        self.moxx = mox.Mox()

    def tearDown(self):
        self.moxx.UnsetStubs()

    def test_login(self):
        user = User.objects.create(username='userfoo')
        user.backend = ''
        view = LoginView()
        request = RequestFactory()
        request.META = {}
        request.user = None
        request.session = self.client.session
        request.session.create()
        view.request = request

        form = self.moxx.CreateMock(UsernameLoginForm)
        form.get_user().AndReturn(user)

        self.moxx.ReplayAll()
        view.form_valid(form)
        self.moxx.VerifyAll()

        self.assertTrue(request.user)
我希望你仍然会提供一些建议,包括为什么我一开始就不应该做这样的事情