2014-03-05 8 views
8

Um einen Kreis Import zu vermeiden, ich habe eine Funktion zu definieren gezwungen, die wie folgt aussieht:Patch über eine Funktion innerhalb einer anderen Funktion importiert

# do_something.py 

def do_it(): 
    from .helpers import do_it_helper 
    # do stuff 

Jetzt würde ich diese in der Lage sein mögen zu testen Funktion, mit do_it_helper gepatcht. Wenn der Import ein Top-Level-Import wäre, würde

class Test_do_it(unittest.TestCase): 
    def test_do_it(self): 
     with patch('do_something.do_it_helper') as helper_mock: 
      helper_mock.return_value = 12 
      # test things 

würde gut funktionieren. Allerdings gibt den Code über mir:

AttributeError: <module 'do_something'> does not have the attribute 'do_it_helper' 

Aus einer Laune heraus, ich habe auch versucht, die Patch-Anweisung zu ändern zu:

with patch('do_something.do_it.do_it_helper') as helper_mock: 

Aber das erzeugte einen ähnlichen Fehler. Gibt es eine Möglichkeit, diese Funktion zu verspotten, da ich gezwungen bin, sie in der Funktion zu importieren, in der sie verwendet wird?

Antwort

16

Sie sollten helpers.do_it_helper verspotten:

class Test_do_it(unittest.TestCase): 
    def test_do_it(self): 
     with patch('helpers.do_it_helper') as helper_mock: 
      helper_mock.return_value = 12 
      # test things 

Hier ist ein Beispiel Mock mit auf os.getcwd():

import unittest 
from mock import patch 


def get_cwd(): 
    from os import getcwd 
    return getcwd() 


class MyTestCase(unittest.TestCase): 
    @patch('os.getcwd') 
    def test_mocked(self, mock_function): 
     mock_function.return_value = 'test' 
     self.assertEqual(get_cwd(), 'test') 

Hoffnung, das hilft.

+0

Das funktioniert völlig! Wo zu patchen war immer verwirrend für mich. Die Faustregel aus den Dokumenten ist "Patch, wo ein Objekt nachgeschlagen wird, das ist nicht unbedingt derselbe Ort, an dem es definiert ist." In diesem Fall patchen Sie jedoch, wo es definiert ist. Warum das? – Wilduck

+0

@Wilduck gut, achten Sie auf dieses 'notwendig' Wort - klingt ein bisschen "zweischneidig" :) – alecxe

Verwandte Themen