["python","unit-testing","mocking"]
How to properly use mock in python with unittest setUp

In my attempt to learn TDD, trying to learn unit testing and using mock with python. Slowly getting the hang of it, but unsure if I'm doing this correctly. Forewarned: I'm stucking using python 2.4 because the vendor API's come as pre-compiled 2.4 pyc files, so I'm using mock 0.8.0 and unittest ( not unittest2 ) Given this example code 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 Now in my test case file 'test_myclass.py', I want to mock the ldap object out. ldap.initialize returns the ldap.ldapobject.SimpleLDAPObject, so I figured that'd be the method I'd have to mock out. 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 Leads me to a couple of questions: Does that look right? :) Is that the proper way to try and mock an object that gets instantiated within the class I'm testing? Is it ok to be calling the @patch decorator on setUp or is this going to cause weird side effects? Is there anyway to get mock to raise the ldap.INVALID_CREDENTIALS exception without having to import the exception into my testcase file? Should I be using patch.object() instead and if so, how? Thanks.
You can use patch() as a class decorator, not just as a function decorator. You can then pass in the mocked function as before: @patch('mymodule.SomeClass') class MyTest(TestCase): def test_one(self, MockSomeClass): self.assertIs(mymodule.SomeClass, MockSomeClass) See: Applying the same patch to every test method (which also lists alternatives) It makes more sense to set up the patcher this way on setUp if you want the patching to be done for all the test methods.