0

I am trying to mock the below function but I'm not sure how to mock the Connection response:

def get_user_res(user, pass):
    res = None
    server = Server('my_server')
    connnection = Connection(server, user, pass, strategy=SAFE_SYNC, auto_bind=True)
    if connection.bind():
        connection.search(search_base, search_filter, SUBTREE)
        res = connection.response
        connection.unbind()
    return res
@mock.patch("ldap3.Server")
@mock.patch("ldap3.Connection.response")
def test_get_user_res(mock_connection, mock_server):
    mock_connection.return_value = ""
    retrived_res = get_user_res("fake_user","fake_password")
    expected_res = ""
    assert retrived_res == expected_res
Incognito
  • 135
  • 4
  • 14
  • It helps if, when asking a question, you post a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). The code you've posted has syntax errors, and the test makes use of a fixture for which you don't show the definition. This makes it difficult for us to help, since the obvious answer is "you spelled 'connection' with too many n's". – larsks Jan 06 '21 at 02:25

1 Answers1

2

The root problem is that you're mocking the wrong things. If you have a file named ldapclient.py that contains your get_user_rest method, like this (note that I've rewritten things a bit to make our lives easier when writing tests):

import ldap3

server = ldap3.Server('my_server')
search_base = 'dc=example, dc=com'


def get_user_res(user, password, search_filter=None):
    res = None

    connection = ldap3.Connection(
        server, user, password,
        client_strategy=ldap3.SAFE_SYNC, auto_bind=True)

    if connection.bind():
        res = connection.search(search_base, search_filter, ldap3.SUBTREE)
        connection.unbind()

    return res

Then what you need to mock is the ldap3.Connection class. But since your test is in a different module, you'll need to call @mock.patch('ldapclient.ldap3.Connection), assuming that your test is defined like this:

import ldap3

from unittest import mock

import ldapclient


@mock.patch("ldapclient.ldap3.Connection")
def test_get_user_res(mock_connection_class):
    mock_connection = mock.Mock()
    mock_connection.search.return_value = 'fake_return'
    mock_connection_class.return_value = mock_connection

    retrived_res = ldapclient.get_user_res("fake_user", "fake_password")
    expected_res = "fake_return"
    assert retrived_res == expected_res

There are a few things to note here:

  1. As mentioned earlier, because we have import ldapclient, we need to mock ldapclient.ldap3.Connection.
  2. We make the ldap3.Connection class return a new mock.Mock object, since we want to be able to mock methods on the object returned when calling connection = ldap3.Connection(...)
  3. We make the search method return a fake value so that we can ensure it gets called as expected.
larsks
  • 277,717
  • 41
  • 399
  • 399
  • Thanks for the help! I have one more question. How can I change the ```mock_connection.search.return_value``` to return a json object? Because when I am trying to parse ```response[0]['attributes']['displayname']``` in main function, it is returning Mock object is not subscriptable. I am passing attributes=["displayname"] in connection.search(). – Incognito Jan 06 '21 at 14:21
  • You set the return value to anything you want. E.g., if you want it to return a list or dictionary (which is what I think you mean by "JSON object"), you could set `mock_connection.search.return_value = [{'attributes': {'displayname': 'foo'}}]` – larsks Jan 06 '21 at 14:34
  • Thanks a lot. I got it to work but you should change mock_connection.search.return_value to mock_connection.response.return_value in your answer. – Incognito Jan 06 '21 at 15:37
  • Actually, if you look at the code in my answer, I never request the `response` attribute, so that wouldn't make sense for this example. – larsks Jan 06 '21 at 15:51
  • A good background read on this - helped me understand why my issue similar to the above wasn't working: https://nedbatchelder.com/blog/201908/why_your_mock_doesnt_work.html – Chris White Nov 11 '21 at 06:11