Ich möchte verstehen, wie @patch
eine Funktion aus einem importierten Modul.
Hier bin ich bisher.
app / mocking.py:
from app.my_module import get_user_name
def test_method():
return get_user_name()
if __name__ == "__main__":
print "Starting Program..."
test_method()
app / my_module / __ init__.py:
def get_user_name():
return "Unmocked User"
test / mock-test.py:
import unittest
from app.mocking import test_method
def mock_get_user():
return "Mocked This Silly"
@patch('app.my_module.get_user_name')
class MockingTestTestCase(unittest.TestCase):
def test_mock_stubs(self, mock_method):
mock_method.return_value = 'Mocked This Silly')
ret = test_method()
self.assertEqual(ret, 'Mocked This Silly')
if __name__ == '__main__':
unittest.main()
Dies funktioniert nicht wie erwartet. Das "gepatchte" Modul gibt einfach den nicht gesperrten Wert von zurück get_user_name
. Wie verspotte ich Methoden aus anderen Paketen, die ich in einen zu testenden Namespace importiere?
Mock
Spottbibliothek wie zu verwenden , die in python3.3 + as enthalten istunittest.mock
.Antworten:
Wenn Sie den
patch
Decorator aus demunittest.mock
Paket verwenden, patchen Sie nicht den Namespace, aus dem das Modul importiert wird (in diesem Fallapp.my_module.get_user_name
), sondern patchen ihn in den zu testenden Namespaceapp.mocking.get_user_name
.Um das oben genannte zu tun,
Mock
versuchen Sie etwas wie das Folgende:Die Standardbibliotheksdokumentation enthält einen nützlichen Abschnitt , der dies beschreibt.
quelle
get_user_name
ist in einem anderen Modul alstest_method
. Gibt es eine Möglichkeit, etwas in einem Submodul zu verspotten? Ich habe es unten auf hässliche Weise repariert.get_user_name
sich das Modul in einem anderen Modul befindet alstest_method
seit dem Importieren.app.mocking
Es befindet sich im selben Namespace.get_user_name_patch
.Während die Antwort von Matti John Ihr Problem löst (und mir auch geholfen hat, danke!), Würde ich jedoch vorschlagen, die Ersetzung der ursprünglichen Funktion 'get_user_name' durch die verspottete zu lokalisieren. Auf diese Weise können Sie steuern, wann die Funktion ersetzt wird und wann nicht. Auf diese Weise können Sie auch mehrere Ersetzungen im selben Test vornehmen. Verwenden Sie dazu die 'with'-Anweisung auf ziemlich ähnliche Weise:
quelle
patch
als Dekorateur oder Kontextmanager verwenden, ist für den Anwendungsfall spezifisch. Sie könnenpatch
beispielsweise als Dekorateur einen Wert für alle Tests in einerxunit
oder einerpytest
Klasse verspotten, während es in anderen Fällen nützlich ist, über die fein abgestimmte Steuerung zu verfügen, die der Kontextmanager bietet.