测试帖子请求时Django消息中间件问题

Emi*_*nte 4 python testing django pytest

我正在尝试测试将消息添加到重定向成功页面的UpdateView。看来我的问题来自messagespytest返回:

django.contrib.messages.api.MessageFailure:您必须先安装django.contrib.messages.middleware.MessageMiddleware才能添加消息

我的测试代码是:

def test_authenticated_staff(self, rf):
    langues = LanguageCatalog.objects.create(
        lang_src='wz',
        lang_dest='en',
        percent='4'
    )
    req = rf.get(reverse("dashboard.staff:lang-update", kwargs={'pk': langues.pk}))
    data = {'lang_src': 'it',
            'lang_dest': 'en',
            'percent': '34'}
    req = rf.post(reverse(
        "dashboard.staff:lang-update", kwargs={'pk': langues.pk}), data=data)
    req.user = UserFactory()
    resp = views.LangUpdateView.as_view()(req, pk=langues.pk)

Run Code Online (Sandbox Code Playgroud)

我精确MessageMiddlewareMIDDLEWARE设置中存在。我用Django==2.0.13

Emi*_*nte 6

我找到了解决方案。为了测试这样的请求,您需要首先用会话和消息注释它。实际上,这意味着添加以下行:

from django.contrib.messages.middleware import MessageMiddleware
from django.contrib.sessions.middleware import SessionMiddleware

# in your test method:
"""Annotate a request object with a session"""
middleware = SessionMiddleware()
middleware.process_request(req)
req.session.save()

"""Annotate a request object with a messages"""
middleware = MessageMiddleware()
middleware.process_request(req)
req.session.save()

# and then (in my case)
resp = views.LangUpdateView.as_view()(req, pk=langues.pk)
Run Code Online (Sandbox Code Playgroud)

  • 当您使用 `RequestFactory` 时,只会运行视图,而不是中间件。如果您使用 [请求客户端](https://docs.djangoproject.com/en/2.2/topics/testing/tools/#default-test-client),那么中间件将运行,您不必手动注释请求对象。 (2认同)

小智 5

您还可以将手动请求注释移动到一个单独的上下文管理器中,该管理器可以在多个测试中重复使用,代码如下所示:

import contextlib

from django.contrib.messages.middleware import MessageMiddleware
from django.contrib.sessions.middleware import SessionMiddleware


@contextlib.contextmanager
def middleware(request):
    """Annotate a request object with a session"""
    middleware = SessionMiddleware()
    middleware.process_request(request)
    request.session.save()

    """Annotate a request object with a messages"""
    middleware = MessageMiddleware()
    middleware.process_request(request)
    request.session.save()
    yield request


def test_authenticated_staff(self, rf):
    langues = LanguageCatalog.objects.create(
        lang_src='wz',
        lang_dest='en',
        percent='4'
    )
    req = rf.get(reverse("dashboard.staff:lang-update", kwargs={'pk': langues.pk}))
    data = {'lang_src': 'it',
            'lang_dest': 'en',
            'percent': '34'}
    req = rf.post(reverse("dashboard.staff:lang-update", kwargs={'pk': langues.pk}), data=data)
    req.user = UserFactory()
    with middleware(req):  # << !
        resp = views.LangUpdateView.as_view()(req, pk=langues.pk)

Run Code Online (Sandbox Code Playgroud)