我有一个需要测试的函数,它以请求作为参数。它没有通过 URL 作为视图公开,因此我无法使用测试客户端对其进行测试。
我需要向其传递一个请求对象,并且请求对象需要启用消息中间件,因为函数中使用了消息中间件。
我正在使用 RequestFactory 来创建我的请求。 文档说:
不支持中间件。如果视图需要正常运行,会话和身份验证属性必须由测试本身提供。
如何使用RequestFactory设置消息中间件?我想我还需要会话中间件来使消息中间件工作
这是我的测试当前在使用普通 RequestFactory 时产生的错误。
MessageFailure: You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware
这是我正在测试的函数,以防它有助于理解这个问题:
from django.contrib import messages as django_messages
def store_to_request(self, request):
"""
Place all the messages stored in this class into message storage in
the request object supplied.
:param request: The request object to which we should store all the messages
:return: Does not return anything
"""
for message in self._messages:
django_messages.add_message(request, message.level, message.message, message.extra_tags,
message.fail_silently)
这个问题被提出了,所以正如那里所说,您可以使用该代码修复您的单元测试:
from django.contrib.messages.storage.fallback import FallbackStorage
setattr(request, 'session', 'session')
messages = FallbackStorage(request)
setattr(request, '_messages', messages)
如果您不需要测试请求对象本身的行为,您可以使用 mock 库而不是 RequestFactory 来模拟请求,例如:
import mock
request = mock.MagicMock()
# Call your function using the mocked request
store_to_request(request)
与 Danag 的答案有效等效的方法是,在将请求对象传递给视图/函数之前,通过会话和消息中间件的 process_request 方法(按顺序)传递请求对象:
from django.contrib.sessions.middleware import SessionMiddleware
from django.contrib.messages.middleware import MessageMiddleware
request = request_factory.get("/")
sm = SessionMiddleware(lambda x: x)
sm.process_request(request)
mm = MessageMiddleware(lambda x: x)
mm.process_request(request)
或者为了方便起见,采用一种方法:
class MessageDependentTests(TestCase):
request_factory = RequestFactory()
session_middleware = SessionMiddleware(lambda x: x)
message_middleware = MessageMiddleware(lambda x: x)
def prepare_request(self, request):
self.session_middleware.process_request(request)
self.message_middleware.process_request(request)
def test_something(self):
request = self.request_factory.get('/')
self.prepare_request(request)
response = my_view(request)
# test response below