Search code examples
pythonpython-2.7unit-testingmockingpsycopg2

How to mock psycopg2 cursor object?


I have this code segment in Python2:

def super_cool_method():
    con = psycopg2.connect(**connection_stuff)
    cur = con.cursor(cursor_factory=DictCursor)
    cur.execute("Super duper SQL query")
    rows = cur.fetchall()

    for row in rows:
        # do some data manipulation on row
    return rows

that I'd like to write some unittests for. I'm wondering how to use mock.patch in order to patch out the cursor and connection variables so that they return a fake set of data? I've tried the following segment of code for my unittests but to no avail:

@mock.patch("psycopg2.connect")
@mock.patch("psycopg2.extensions.cursor.fetchall")
def test_super_awesome_stuff(self, a, b):
    testing = super_cool_method()

But I seem to get the following error:

TypeError: can't set attributes of built-in/extension type 'psycopg2.extensions.cursor'

Solution

  • Since the cursor is the return value of con.cursor, you only need to mock the connection, then configure it properly. For example,

    query_result = [("field1a", "field2a"), ("field1b", "field2b")]
    with mock.patch('psycopg2.connect') as mock_connect:
        mock_connect.cursor.return_value.fetchall.return_value = query_result
        super_cool_method()