Monkey修补了django auth的登录,现在它的测试失败了

时间:2011-03-30 00:35:39

标签: django monkeypatching django-authentication

我的应用程序试图用一些基本的审计/日志记录功能包装django.contrib.auth.views登录和注销视图。我遵循django-axes项目中描述的处方,在运行服务器和其他一些测试时,它按预期工作,透明地没有问题。

代码如下:

from django.contrib.auth import views as auth_views
from myapp.watchers import watch_login

class WatcherMiddleware(object):
    def __init__(self):
        auth_views.login = watch_login(auth_views.login)

def watch_login(func):
    def decorated_login(request, *args, **kwargs):
        #do some stuff
        response = func(request, *args, **kwargs)
        #more stuff
        return response
    return decorated_login

的url:

#Edit: Added project's urls - just using vanilla django's auth login
(r'^accounts/login/$', 'django.contrib.auth.views.login',{"template_name":settings.LOGIN_TEMPLATE }),

但是,在我们的构建工作流程中,我们在django.contrib.auth.tests.views中遇到了一些问题。

具体来说,这些是在django.contrib.auth中失败的测试:

ERROR: test_current_site_in_context_after_login (django.contrib.auth.tests.views.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python26\lib\site-packages\django\contrib\auth\tests\views.py", line 192, in test_current_site_in_context_after_login
    response = self.client.get(reverse('django.contrib.auth.views.login'))
  File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 351, in reverse
    *args, **kwargs)))
  File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 297, in reverse
    "arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'myapp.watchers.decorated_login' with arguments '()' and keyword arguments '{}' not found.

======================================================================
ERROR: test_security_check (django.contrib.auth.tests.views.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python26\lib\site-packages\django\contrib\auth\tests\views.py", line 204, in test_security_check
    login_url = reverse('django.contrib.auth.views.login')
  File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 351, in reverse
    *args, **kwargs)))
  File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 297, in reverse
    "arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'myapp.watchers.decorated_login' with arguments '()' and keyword arguments '{}' not found.

只有这两个测试失败,包含了包装的登录猴子补丁 似乎django auth测试中的reverse()调用与未修补的函数的作用有所不同。

我们采用这种方式进行包装日志记录与使用django 1.3的新认证信号的原因是因为那里提供的日志记录方法只会告诉您是否发生了错误的尝试 - 它不会让您访问请求对象以记录有关该不正确请求的其他信息。在这种情况下修补身份验证表单不会有帮助,因此我们需要包装登录功能。

我的登录功能包装出错了吗?尽管总体功能没有变化,但由于其他副作用导致测试失败,这是否可以预期?

编辑:我正在运行python 2.6.4,django 1.2.5

2 个答案:

答案 0 :(得分:5)

难道你不能简单地将它包装在另一个视图中吗?

<强> urls

url(
    r'^accounts/login/$',
    'accounts.views.login',
    {"template_name":settings.LOGIN_TEMPLATE }
),

<强> accounts.views

from django.contrib.auth import views as auth_views   

def login(request, *args, **kwars):
    # do some stuff    
    response = auth_views.login(request, *args, **kwars)
    # more stuff
    return response

像这样,django.contrib.auth.tests将测试他们为其编写的视图,您可以为自己需要的“更多东西”编写自己的测试。

答案 1 :(得分:3)

我怀疑这是同一个潜在问题that affects django-registration,因为测试运行者只导入当时正在测试的应用的网址 - 即contrib.auth而不是myapp那里various tickets关于事物similar to this issue,但快速扫描它们意味着解决方案是解耦事情,这对我猜测的解决方案来说是不可行的。

另一种方法是使用Fabric文件或Makefile来触发测试的子集,避免因为你的monkeypatch而失败的两个,然后添加两个备用的猿友好测试来替换它们。