2012-04-10 3 views
1

lib.pySpotte ich diese Hilfsfunktion direkt in meinem Django-Test?

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) 

Aber stattdessen ich

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. 

Warum es reverse Aufruf wird statt meiner mock_reverse (es ist nachschlagen urls.py !!) Sie können sehen, calls gibt eine leere Liste zurück. Ich sogar assert mock_reverse.called und es kehrte falsch zurück.

Vielleicht habe ich das nicht erwähnt, aber lib ist nur eine Reihe von Funktionen, es gibt keine Klasse.

Antwort

1

Zwei Dinge. 1. Sie müssen reverse von Django patchen. 2. Sie müssen importieren in den Kontextmanager, um lib Modul Import reverse Mock gemacht.

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

Danke. Nun, wie ich schon sagte, habe ich Michaels Screencast angeschaut, die View-Funktion ruft Poll.objects.get_filter auf, also hat er sich darüber lustig gemacht (ebenso wie das Request-Objekt). Also dachte ich, es wäre das Richtige, da wir uns nicht auf das "Reverse" verlassen wollen. – CppLearner

+0

@CppLearner Ich habe deinen Code erneut gelesen und jetzt verstehe ich nicht, warum du deine 'render_reverse' überhaupt brauchst. Welche Aufgabe löst es? Warum nicht normales "reverse" verwenden? – DrTyrsa

+0

Danke. Ja. Ich habe mich geirrt, 'render_reverse' zu ​​machen, aber lassen Sie uns' render_reverse' als einen Wrapper betrachten, der etwas vor dem Übergeben an irgendwelche eingebauten Django-Funktionen tut. Ich habe bereits 'reverse' gepatcht, warum benutzt es immer noch die eingebaute' reverse'? Mein schlechtes Verständnis war, dass wir beim Patchen die Mock-Version verwenden, also sollte 'render_reverse' nicht den erwarteten Rückgabewert zurückgeben? – CppLearner

0

Sie übergeben keine Schlüsselwortargumente (was ein Wörterbuch ist) und übergeben stattdessen Positionsargumente (das Tupel).

Darüber hinaus übergibt die Proxymethode zum Reverse nur die Schlüsselwortargumente und nicht die Positionsargumente.

Schließlich haben Sie keine URL, die dem angeforderten Muster entspricht - weil Sie keine Schlüsselwortargumente, nur Positionsargumente übergeben haben.

+0

Danke. Warum gibt es kein Wörterbuch zurück? Ich habe sogar 'mock_f.return_value' und' mock_f() 'versucht. Ich habe immer noch den gleichen Fehler. Die erwartete Argumentübergabe ist wie folgt: 'response = render_reverse ('codebundle_homepage', {'args': [cbid]})' und dieser hartcodierte funktioniert. – CppLearner

+0

BTW In 99% der Fälle kümmert sich Django nicht darum, wie Sie die Argumente übergeben. Sie können dieselbe Ansicht mit 'kwargs' und mit' args' umkehren. – DrTyrsa