### Navigation

- index
- next |
- previous |
- mockldap 0.1.4 documentation »

# Overview

The goal of mockldap is to provide a mock instance of LDAPObject in response to any call to ldap.initialize. In the general case, you would register return values for all LDAPObject calls that you expect the code under test to make. Your assertions would then verify that the tested code behaved correctly given this set of return values from the LDAP APIs.

As a convenience, the mock LDAPObject isn’t just a dumb mock object. The typical way to use mockldap is to provide some static directory content and then let `LDAPObject` generate real return values. This will only work for simple LDAP operations–this obviously isn’t a complete Python LDAP server implementation–but those simple operations tend to cover a lot of cases.

## Example

    import unittest
    import ldap

    from mockldap import MockLdap

    class MyTestCase(unittest.TestCase):
        """
        A simple test case showing off some of the basic features of mockldap.
        """
        top = ('o=test', {'o': 'test'})
        example = ('ou=example,o=test', {'ou': 'example'})
        other = ('ou=other,o=test', {'ou': 'other'})
        manager = ('cn=manager,ou=example,o=test', {'cn': 'manager', 'userPassword': ['ldaptest']})
        alice = ('cn=alice,ou=example,o=test', {'cn': 'alice', 'userPassword': ['alicepw']})
        bob = ('cn=bob,ou=other,o=test', {'cn': 'bob', 'userPassword': ['bobpw']})

        # This is the content of our mock LDAP directory. It takes the form
        # {dn: {attr: [value, ...], ...}, ...}.
        directory = dict([top, example, other, manager, alice, bob])

        @classmethod
        def setUpClass(cls):
            # We only need to create the MockLdap instance once. The content we
            # pass in will be used for all LDAP connections.
            cls.mockldap = MockLdap(cls.directory)

        @classmethod
        def tearDownClass(cls):
            del cls.mockldap

        def setUp(self):
            # Patch ldap.initialize
            self.mockldap.start()
            self.ldapobj = self.mockldap['ldap://localhost/']

        def tearDown(self):
            # Stop patching ldap.initialize and reset state.
            self.mockldap.stop()
            del self.ldapobj

        def test_some_ldap(self):
            """
            Some LDAP operations, including binds and simple searches, can be
            mimicked.
            """
            results = _do_simple_ldap_search()

            self.assertEquals(self.ldapobj.methods_called(), ['initialize', 'simple_bind_s', 'search_s'])
            self.assertEquals(sorted(results), sorted([self.manager, self.alice]))

        def test_complex_search(self):
            """
            Some LDAP operations, such as complex searches, are not implemented.
            If you're doing anything nontrivial, you have to set an explicit
            return value for a set of parameters.
            """
            self.ldapobj.search_s.seed('o=test', ldap.SCOPE_SUBTREE, '(|(cn=b*b)(cn=a*e))')([self.alice, self.bob])

            results = _do_complex_ldap_search()

            self.assertEquals(self.ldapobj.methods_called(), ['initialize', 'simple_bind_s', 'search_s'])
            self.assertEquals(sorted(results), sorted([self.alice, self.bob]))

    def _do_simple_ldap_search():
        conn = ldap.initialize('ldap://localhost/')
        conn.simple_bind_s('cn=alice,ou=example,o=test', 'alicepw')
        results = conn.search_s('ou=example,o=test', ldap.SCOPE_ONELEVEL, '(cn=*)')

        return results

    def _do_complex_ldap_search():
        conn = ldap.initialize('ldap://localhost/')
        conn.simple_bind_s('cn=alice,ou=example,o=test', 'alicepw')
        results = conn.search_s('o=test', ldap.SCOPE_SUBTREE, '(|(cn=b*b)(cn=a*e))')

        return results

### Navigation

- index
- next |
- previous |
- mockldap 0.1.4 documentation »