I am trying to write unit test case to test the following method by mocking the database. How to mock the database connection without actually connecting to the real database server.I tried with sample test case. I am not sure if that is right way to do it. Please correct me if I am wrong.
//MySQL.py
class MySQL():
retry_interval = 20000
def link(self, server,port):
try:
return pymysql.connect(server, username='name', passwd='pwd', db='demo', int(port))
sys.stdout.write('Connected to database at {}:{}\n'.format(server,port))
except:
sys.stderr.write('Retry database connection in {} ms...\n'.format(self.retry_interval))
sleep(self.retry_interval/1000.0)
continue
//test.py
from unittest.mock import Mock, MagicMock
from unittest.mock import patch
import MySQL
@patch('MySQL.pymysql')
def testLink(self, mysql_mock):
mock_cursor = Mock.MagicMock()
mysql_mock.connect.return_value.cursor.return_value.__enter__.return_value = mock_cursor
The only useful thing you can really test in MySQL.pymysql
is the connect
method, so you might as well patch that directly:
//test.py
from unittest.mock import Mock, MagicMock
from unittest.mock import patch, call
import MySQL
@patch('MySQL.pymysql.connect')
def testLink(self, connect_mock):
# You can configure a return value for the connection if you need to...
connect_mock.return_value = MagicMock(name='connection_return', return_value=...)
# You can now test that your connection is being called...
self.assertEqual(1, connect_mock.call_count)
# You can also check the call parameters...
self.assertEqual(connect_mock.call_args_list[0], call(server, username='name', passwd='pwd',...))