mardi 12 avril 2016

Mocking fails in Django unittest of utils.py

I am trying to write a unittest for a function named search_ldap(), which searches an LDAP server given a particular username. Here is the function definition in utils.py (note: I'm using Python 3):

import ldap3
def search_ldap(username):
    result = ()
    baseDN = "o=Universiteit van Tilburg,c=NL"
    searchFilter = '(uid={})'.format(username)
    attributes = ['givenName', 'cn', 'employeeNumber', 'mail']

    try:
        server = ldap3.Server('ldap.example.com', use_ssl=True)
        conn = ldap3.Connection(server, auto_bind=True)
        conn.search(baseDN, searchFilter, attributes=attributes)
        for a in attributes:
            result += (conn.response[0]['attributes'][a][0], )
    except Exception:
        raise LDAPError('Error in LDAP query')

    return result

Of course I don't want to actually connect to ldap.example.com during testing, so I've decided to use Python's mock object library to mock the Server() and Connection() classes in my unittests. Here is the test code:

from unittest import mock
from django.test import TestCase
class LdapTest(TestCase):
    @mock.patch('ldap3.Server')
    @mock.patch('ldap3.Connection')
    def test_search_ldap(self, mockConnection, mockServer):
        from .utils import search_ldap
        search_ldap('username')
        self.assertTrue(mockServer.called)
        self.assertTrue(mockConnection.called)

This test simply asserts that the mocked Server and Connection objects are instantiated. However, thay don't, because when I run the tests with ./manage.py test I receive the following error:

Creating test database for alias 'default'...
F.
======================================================================
FAIL: test_search_ldap (uvt_user.tests.LdapTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/mock.py", line 1142, in patched
    return func(*args, **keywargs)
  File "/home/jj/projects/autodidact/uvt_user/tests.py", line 28, in test_search_ldap
    self.assertTrue(mockServer.called)
AssertionError: False is not true

----------------------------------------------------------------------
Ran 2 tests in 0.030s

FAILED (failures=1)
Destroying test database for alias 'default'...

Why are my tests failing? How can I successfully mock ldap3's Server and Connection classes?

Aucun commentaire:

Enregistrer un commentaire