0

I have a Python function that connects to a database using pgdb and executes a query.

    def execute_query(credentials, query, data):
        with pgdb.connect(credentials) as conn:
            with conn.cursor() as cur:
                cur.execute(query, data)

I am trying to write a unit test for this function but am having trouble getting mocking to work. I followed the suggestions from this post but am having issues when trying to mock the nested context manager.

The last assert is failing because out is None.

@mock.patch("pgdb.connect")
def test_execute_query(self, mock_connect):
    query_result = "test"

    cursor_mock = MagicMock()
    cursor_mock.cursor.__enter__.return_value.execute = query_result

    mock_connect.return_value.__enter__.return_value = cursor_mock

    out = execute_query(None, None, None)
    mock_connect.assert_called_once_with()
    mock_connect.return_value.__enter__.assert_called_once()

    cursor_mock.cursor.assert_called_once()
    cursor_mock.cursor.__enter__.assert_called_once()

    self.assertEquals(out, query_result)

Does anyone have any suggestions on how I can get this to work?

SW Williams
  • 559
  • 1
  • 5
  • 18
  • `..am having issues ` - what are the issues? – wwii Jan 01 '20 at 02:43
  • My mocked `cursor.execute` is not returning "test". – SW Williams Jan 01 '20 at 02:48
  • 1
    In [the docs](https://docs.python.org/3/library/unittest.mock.html#mocking-magic-methods) there is an example `for mocking objects used as context managers in a with statement` which mocks the `__enter__` method with another `Mock` that has a specific return value. Have you tried that or a variation? – wwii Jan 01 '20 at 03:23
  • Does this answer your question? [Mocking two functions with patch for a unit test](https://stackoverflow.com/questions/15763394/mocking-two-functions-with-patch-for-a-unit-test) – wwii Jan 01 '20 at 04:02

0 Answers0