2012-04-10 43 views
1

lib.py我在我的Django测试中嘲笑这个帮助函数吗?

from django.core.urlresolvers import reverse 
def render_reverse(f, kwargs): 
    """ 
    kwargs is a dictionary, usually of the form {'args': [cbid]} 
    """ 
    return reverse(f, **kwargs) 

tests.py

from lib import render_reverse, print_ls 

class LibTest(unittest.TestCase): 

def test_render_reverse_is_correct(self): 
    #with patch('webclient.apps.codebundles.lib.reverse') as mock_reverse: 
    with patch('django.core.urlresolvers.reverse') as mock_reverse: 
     from lib import render_reverse 
     mock_f = MagicMock(name='f', return_value='dummy_views') 
     mock_kwargs = MagicMock(name='kwargs',return_value={'args':['123']}) 
     mock_reverse.return_value = '/natrium/cb/details/123' 
     response = render_reverse(mock_f(), mock_kwargs()) 

     print mock_reverse.mock_calls # prints [] 
    print mock_reverse.mock_calls # prints [] 
    self.assertTrue('/natrium/cb/details/' in response) 

但是,相反,我得到

File "/var/lib/graphyte-webclient/graphyte-webenv/lib/python2.6/site-packages/django/core/urlresolvers.py", line 296, in reverse 
    "arguments '%s' not found." % (lookup_view_s, args, kwargs)) 
NoReverseMatch: Reverse for 'dummy_readfile' with arguments '('123',)' and keyword arguments '{}' not found. 

为什么叫reverse,而不是我mock_reverse(它是查找我的urls.py !!) 你可以看到calls返回一个空的列表。我甚至assert mock_reverse.called,它返回false。

也许我没有提到这个,但是lib只是一堆函数,没有类。

回答

1

两件事。 1.你需要从Django补丁reverse。 2.您需要在上下文管理器中进行导入,以使lib模块导入模拟为reverse

from lib import print_ls 

class LibTest(unittest.TestCase): 

    def test_render_reverse_is_correct(self): 
     with patch('django.core.urlresolvers.reverse') as mock_reverse: 
      from lib import render_reverse 
      mock_f = MagicMock(name='f', return_value='dummy_view') 
      mock_kwargs = MagicMock(name='kwargs',return_value={'args':['123']}) 
      mock_reverse.return_value = '/natrium/cb/details/123' 
      response = render_reverse(mock_f, mock_kwargs) 

     self.assertTrue('/natrium/cb/details/' in response) 
+0

谢谢。好吧,就像我说过的,我看了Michael的屏幕录像,视图函数调用了Poll.objects.get_filter,所以他嘲笑了这一点(以及请求对象)。所以我认为这是正确的做法,因为我们不想依赖实际的“反向”。 – CppLearner 2012-04-11 04:02:10

+0

@CppLearner我已经重读了你的代码,现在我不明白你为什么需要'render_reverse'。它解决了什么任务?为什么不使用正常的'reverse'? – DrTyrsa 2012-04-11 08:07:20

+0

谢谢。是啊。我错了'render_reverse',但让我们把'render_reverse'想象成一个封装器,在传递给任何django内置函数之前做一些事情。我已经修补了'reverse',为什么仍然使用内置的'reverse'?我可怜的理解是,当我们修补我们使用的模拟版本,所以不应该'render_reverse'返回我的预期返回值? – CppLearner 2012-04-11 18:27:18

0

你没有传递任何关键字参数(这是一个字典),而是传递位置参数(元组)。

此外,您的代理方法只能通过关键字参数而不是位置参数。

最后,你没有匹配请求模式的URL - 因为你没有传递任何关键字参数,只有位置参数。

+0

谢谢。为什么它没有返回字典?我甚至尝试过'mock_f.return_value'和'mock_f()'。我仍然以相同的错误结束。 预期的参数传递如下所示:'response = render_reverse('codebundle_homepage',{'args':[cbid]})'这个硬编码将起作用。 – CppLearner 2012-04-10 09:17:23

+0

顺便说一句,在99%的情况下,Django并不关心你传递参数的方式。你可以用'kwargs'和'args'来“倒转”相同的视图。 – DrTyrsa 2012-04-10 10:38:51