I am trying to write unit test for one of my module using pymysql as follows:
def execute(self, query):
try:
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='',
db='mysql')
cur = conn.cursor()
cur.execute(query)
except pymysql.Error as e:
raise
except Exception as e:
raise
While writing unit test for the above function, I am mocking pysql as follows @patch(my_package.my_module.pymysql)
. As a result pymysql.error
is also becoming mocked. So while testing the failure scenario as follows:
@patch('my_package.my_module.pymysql')
def test_execute_with_failure(self, mock_pymysql):
...
self.my_obj.cur.execute.side_effect = pymysql.Error
with self.assertRaises(pymysql.Error) as context:
_ = self.my_obj.execute(query="SELECT FOO FROM BAR")
I am getting the below error:
TypeError: catching classes that do not inherit from BaseException is not allowed
In this regard I have gone through this: Can't catch mocked exception because it doesn't inherit BaseException. But I am not getting how to make this work for pymysql
.
EDIT 1: As suggested, I have tried to mock only pymysql.connect
as follows:
@patch('my_package.my_module.pymysql.connect')
def test_execute_with_failure(self, mock_pymysql_conn):
cursor = MagicMock()
mock_pymysql_conn.return_value.cursor = cursor
self.my_obj.cur = cursor
self.my_obj.cur.execute.side_effect = pymysql.Error
with self.assertRaises(pymysql.Error) as context:
_ = self.my_obj.execute(query="SELECT FOO FROM BAR")
But, I am getting here, as follows:
E AttributeError: <module 'pymysql' from '/my_project/venv/lib/python3.7/site-packages/pymysql/__init__.py'> does not have the attribute ''
EDIT 2: I have tried with below approach as well:
@patch('my_package.my_module.pymysql')
def test_execute_with_failure(self, mock_pymysql):
conn = Mock()
mock_pymysql.connect.return_value = conn
cursor = MagicMock()
conn.return_value.cursor = cursor
self.my_obj.cur = cursor
mock_pymysql.Error = type('PymysqlError', (Exception,), {})
self.my_obj.cur.execute.side_effect = mock_pymysql.Error
with self.assertRaises(mock_pymysql.Error) as context:
_ = self.my_obj.execute(query="SELECT * FROM TEST")
Still the same error as Edit 1.