Wie man Mock in Python mit unittest setUp richtig benutzt
Bei meinem Versuch, TDD zu lernen, habe ich versucht, Unit-Tests zu lernen und Mock mit Python zu verwenden. Langsam den Dreh raus, aber unsicher, ob ich das richtig mache. Vorwarnung: Ich bleibe bei der Verwendung von Python 2.4, da die Hersteller-APIs als vorkompilierte 2.4-Pyc-Dateien vorliegen. Daher verwende ich Mock 0.8.0 und Unittest (nicht Unittest2).
In Anbetracht dieses Beispielcodes in 'mymodule.py'
import ldap
class MyCustomException(Exception):
pass
class MyClass:
def __init__(self, server, user, passwd):
self.ldap = ldap.initialize(server)
self.user = user
self.passwd = passwd
def connect(self):
try:
self.ldap.simple_bind_s(self.user, self.passwd)
except ldap.INVALID_CREDENTIALS:
# do some stuff
raise MyCustomException
Jetzt möchte ich in meiner Testfalldatei 'test_myclass.py' das ldap-Objekt verspotten. ldap.initialize gibt das ldap.ldapobject.SimpleLDAPObject zurück, daher habe ich mir gedacht, dass dies die Methode ist, die ich ausnutzen müsste.
import unittest
from ldap import INVALID_CREDENTIALS
from mock import patch, MagicMock
from mymodule import MyClass
class LDAPConnTests(unittest.TestCase):
@patch('ldap.initialize')
def setUp(self, mock_obj):
self.ldapserver = MyClass('myserver','myuser','mypass')
self.mocked_inst = mock_obj.return_value
def testRaisesMyCustomException(self):
self.mocked_inst.simple_bind_s = MagicMock()
# set our side effect to the ldap exception to raise
self.mocked_inst.simple_bind_s.side_effect = INVALID_CREDENTIALS
self.assertRaises(mymodule.MyCustomException, self.ldapserver.connect)
def testMyNextTestCase(self):
# blah blah
Führt mich zu ein paar Fragen:
Sieht das richtig aus? :)Ist dies der richtige Weg, um ein Objekt zu verspotten, das innerhalb der von mir getesteten Klasse instanziiert wird?Ist es in Ordnung, den @ patch-Dekorator bei setUp aufzurufen, oder wird dies seltsame Nebenwirkungen verursachen?Gibt es eine Möglichkeit, die Ausnahmebedingung ldap.INVALID_CREDENTIALS zu verspotten, ohne die Ausnahmebedingung in meine Testfalldatei importieren zu müssen?Sollte ich stattdessen patch.object () verwenden und wenn ja, wie?Vielen Dank.