0

I've been trying to test the below metheod specially the if block and have tried multiple things like patching, mocking in various combinations of pyodbc but I've not been able to mock the if condition.

def execute_read(self, query):
      dbconn = pyodbc.connect(self.connection_string, convert_unicode=True)
      with dbconn.cursor() as cur:
           cursor = cur.execute(query)
           if not cursor.messages:
                res = cursor.fetchall()
           else:
               raise Exception(cursor.messages[0][1])
           return res;

      # unit test method
      @patch.object(pyodbc, 'connect')
      def test_execute_read(self, pyodbc_mock):
            pyodbc_mock.return_value = MagicMock()
            self.assertIsNotNone(execute_read('query'))
            
              

I've read the docs of unittest.mock, but I haven't found a way to get this above if condition covered. Thank you.

vermachint
  • 93
  • 1
  • 9

1 Answers1

0

You would want to patch the Connection class (given the Cursor object is immutable) and supply a return value for covering the if block. Something that may look like:

with patch.object("pyodbc.Connection") as conn:
    conn.cursor().messages = []
    ...

Tried this with sqlite3 and that worked for me.


Here's an example of using the patch object, something I wrote for frappe/frappe:

    def test_db_update(self):
        with patch.object(Database, "sql") as sql_called:
            frappe.db.set_value(
                self.todo1.doctype,
                self.todo1.name,
                "description",
                f"{self.todo1.description}-edit by `test_for_update`",
            )
            first_query = sql_called.call_args_list[0].args[0]
            second_query = sql_called.call_args_list[1].args[0]

            self.assertTrue(sql_called.call_count == 2)
            self.assertTrue("FOR UPDATE" in first_query)
gavin
  • 793
  • 1
  • 7
  • 19