0

I am trying to mock an object defined inside a ContextManager, and cannot figure it out. Paraphrasing code to test:

def my_func():
  # psycopg2 connection and cursor
  with conn.connection.cursor() as cursor:
     data = cur.execute(<some_sql>)
     writer = csv.writer(<some_open_file>)
     writer.writerows(data)

Now I need to unit test this

@patch_import('csv.writer')
def test_my_func(mock_csv_writer):

    mock_cursor = MagicMock(return_value=MagicMock())
    mock_cursor.return_value.__enter__.return_value = MagicMock()
    mock_conn = MagicMock(connection=MagicMock(cursor=mock_cursor))
    mock_ctx_entry = mock_cursor.return_value.__enter__()

    with mock.patch.object(mock_ctx_entry, "execute") as mock_execute,\
       mock.patch.object(mock_csv_writer, "writerows") as mock_write:
           # Invoke code that calls function
           mock_execute.assert_called
           mock_write.assert_called

However, this does not work because the writer inside the cursor context manager is not the same as the one patched. So how can one mock objects defined inside a context manager?

In fact any documentation on chaining the enter for context managers and their return values would be helpful too.

SeriousGal
  • 21
  • 1

0 Answers0