Pages

Monday, 25 April 2011

Mocking LDAP calls with minimock in python

When using unittest in python you often need to mock objects and calls to those objects.

You don't need _an_entire_ LDAP server just to test a search nor you need a full blown SMTP server to test a function that accidentally sends a mail (that you don't want to send while testing anyway).

So minimock is one easy way (the easiest I found) to do the job.

What the docs don't really tell you (nor does a google search) is how to return real things when you need to call a method of an object.

Say you have some code like this:
import ldap
class MyClass:
...
    def ldapsearch(self, uid):
        self.conn = ldap.open(self.conf.ldapserver)
        self.conn.bind_s(binddn, bindpw, ldap.AUTH_SIMPLE)
        self.conn.search_s(basedn, ldap.SCOPE_SUBTREE, 'uid=%s' % uid, ['uid'])
        return True

and you want to test this and moreover you want that search to return a given set of data.

from minimock import Mock
import ldap
from my_program import MyClass

class MyClassTest(unittest.TestCase):
...
    def test_ldapsearch(self):
        # create your fake ldap connection
        ldap.open = Mock('ldap.open')
        ldap.open.mock_returns = Mock('ldap_connection')
        # instantiate your class
        myclass = MyClass()
        # now tell to minimock that in case we do a search_s on 
        # a conn method this should be intercepted and mocked
        # returning a testuser1 value the way LDAP would do
        myclass.conn.search_s.mock_returns = [[1,{'uid':['testuser1'], \
                                        'mail':['test.user1@mail.com']}]]
        # This will return testuser1 no matter what
        # and show you on screen the operations performed
        self.assertEqual(myclass.ldapsearch('onetwoonetwo'), True)

This should help you inject whatever values you want there and also clarify a bit how to minimock wants you to think (that is the only way I could make it work).

No comments:

Post a Comment