Jak poprawnie używać makiety w pythonie z ustawieniem unittest
Próbując nauczyć się TDD, próbuję nauczyć się testowania jednostkowego i używania makiety z pytonem. Powoli zaczynam to rozumieć, ale nie wiem, czy robię to poprawnie. Forewarned: Utknąłem przy użyciu Pythona 2.4, ponieważ API dostawcy przychodzi jako skompilowane pliki 2.4 pyc, więc używam mock 0.8.0 i unittest (nie unittest2)
Biorąc pod uwagę ten przykładowy kod w '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
Teraz w moim pliku przypadków testowych 'test_myclass.py' chcę wykluczyć obiekt ldap. ldap.initialize zwraca ldap.ldapobject.SimpleLDAPObject, więc pomyślałem, że będzie to metoda, którą będę musiał wykpić.
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
Prowadzi mnie do kilku pytań:
Czy to wygląda dobrze? :)Czy jest to właściwy sposób, aby spróbować wyszydzić obiekt, który zostanie utworzony w klasie, którą testuję?Czy można dzwonić do dekoratora @patch na setUp, czy też spowoduje to dziwne efekty uboczne?Czy mimo to uzyskać mock, aby podnieść wyjątek ldap.INVALID_CREDENTIALS bez konieczności importowania wyjątku do mojego pliku testcase?Czy zamiast tego powinienem używać patch.object (), a jeśli tak, to w jaki sposób?Dzięki.