Schedule a demo

Testing LDAP connections

When your Zato service looks up users in Active Directory, authenticates against LDAP, or queries organizational data, you need to test that logic without a real directory server. This page shows how to mock LDAP responses so your tests run fast and don't require directory access.

Note: If you're new to unit testing with Zato, check the tutorial first.

Basic usage

Services access LDAP connections like this:

from zato.server.service import Service

class GetUserFromLDAP(Service):
    name = 'ldap.user.get'
    input = 'email'

    def handle(self):
        conn = self.out.ldap['corporate-directory'].conn
        entries = conn.get(self.request.input.email)

        if entries:
            user = entries[0]
            self.response.payload = {
                'name': user['cn'],
                'email': user['mail'],
                'department': user['department']
            }
        else:
            self.response.payload = {'error': 'User not found'}

Mock the LDAP results in your test:

from zato_testing import ServiceTestCase
from myapp.services import GetUserFromLDAP

class TestGetUserFromLDAP(ServiceTestCase):

    def test_returns_user(self):

        # Configure LDAP results with ldap: prefix
        self.set_response('ldap:corporate-directory', [
            {
                'cn': 'John Smith',
                'mail': 'john.smith@example.com',
                'department': 'Engineering'
            }
        ])

        service = self.invoke(GetUserFromLDAP, email='john.smith@example.com')

        self.assertEqual(service.response.payload['name'], 'John Smith')
        self.assertEqual(service.response.payload['department'], 'Engineering')

Note the ldap: prefix to distinguish LDAP connections from REST connections.

Mock search operations:

class SearchUsers(Service):
    name = 'ldap.users.search'
    input = 'department'

    def handle(self):
        conn = self.out.ldap['corporate-directory'].conn
        entries = conn.search(
            filter=f'(department={self.request.input.department})'
        )

        self.response.payload = {
            'users': [{'name': e['cn'], 'email': e['mail']} for e in entries]
        }
class TestSearchUsers(ServiceTestCase):

    def test_finds_users_in_department(self):

        self.set_response('ldap:corporate-directory', [
            {'cn': 'Alice', 'mail': 'alice@example.com'},
            {'cn': 'Bob', 'mail': 'bob@example.com'},
            {'cn': 'Carol', 'mail': 'carol@example.com'}
        ])

        service = self.invoke(SearchUsers, department='Engineering')

        self.assertEqual(len(service.response.payload['users']), 3)

Empty results

Test handling of users not found:

class TestUserNotFound(ServiceTestCase):

    def test_handles_missing_user(self):

        self.set_response('ldap:corporate-directory', [])

        service = self.invoke(GetUserFromLDAP, email='unknown@example.com')

        self.assertEqual(service.response.payload['error'], 'User not found')

Multiple entries

Return multiple LDAP entries:

class TestMultipleEntries(ServiceTestCase):

    def test_returns_all_matches(self):

        self.set_response('ldap:corporate-directory', [
            {'cn': 'John Smith', 'mail': 'john.smith@example.com'},
            {'cn': 'John Doe', 'mail': 'john.doe@example.com'},
            {'cn': 'John Adams', 'mail': 'john.adams@example.com'}
        ])

        service = self.invoke(SearchUsers, name='John*')

        self.assertEqual(len(service.response.payload['users']), 3)

See also