这是我试图用测试覆盖的两行代码:
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 扩展的登录表单的正确方法,但我不得不自己从管理登录 View 中挖掘代码,因此需要进行适当的测试。
我在获取测试环境以在 session 中设置用户时遇到问题。 RequestFactory 没有 session 支持,所以这是我尝试过的:
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 生成的 session 附加到 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)
我希望您仍能提供建议,包括为什么我一开始就不应该做这样的事情。
关于Django登录测试session问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30740840/