python - Mocking Only One Function of a Class -


i write unit test can ensure sql statement in function call schematically correct. should test execution of call. mock call commit, no insertions database take place. i'm using psycopg2 tests.

i have function like:

def test_insert(a, b, c):     con = psycopg2.connect(os.environ['pgdb'])     cur = con.cursor()     cur.execute('insert test_table values ({a}, {b}, {c})'.format(a=a, b=b, c=c))     con.commit()     con.close() 

when calling test_insert(1,2,3) see row inserted table. try mock call. i've taken few approaches far:

@mock.patch('psycopg2.connect') def test(mock_connect, a, b, c):     mock_con = mock_connect.return_value     mock_con.commit.return_value = none     insert_row(a, b, c) 

this seems work not call execution statement. test_insert(1,4,'xyz') fails instance while test(1,4,'xyz') not. next tried mock commit method of connection class in psycopg2:

@mock.patch('psycopg2.extensions.connection.commit') def test_insert(mock_commit, a, b, c):     mock_commit.return_value = none     insert_row(a,b,c) 

but gives me syntax error

traceback (most recent call last):   file "<stdin>", line 1, in <module>   file "/home/a/.virtualenv/test/lib/python2.7/site-packages/mock/mock.py", line 1318, in patched     patching.__exit__(*exc_info)   file "/home/a/.virtualenv/test/lib/python2.7/site-packages/mock/mock.py", line 1480, in __exit__     setattr(self.target, self.attribute, self.temp_original) typeerror: can't set attributes of built-in/extension type 'psycopg2.extensions.connection' 

is there way trying do?

i assume using pytest , not practice name functions starting test_ if not actual tests raise problems testing framework. therefore modified initial snippet follows , named module psyco.py

import psycopg2 import os  def insert(a, b, c):     con = psycopg2.connect(os.environ['pgdb'])     import ipdb; ipdb.set_trace()     cur = con.cursor()     cur.execute('insert test_table values ({a}, {b}, {c})'.format(a=a, b=b, c=c))     con.commit()     con.close() 

next, created test method taking account how patch works , where patch. dealing os environment variables this question can understand why mocked way.

an example implementation of test follows:

from psyco import insert unittest.mock import patch, mock, magicmock import os  @patch.dict(os.environ,{'pgdb':'db_url'}) @patch('psycopg2.connect') def test_insert_function(psycopg2_mock):      x = 1     y = 4     z = 'xyz'     sql_query = 'insert test_table values ({0}, {1}, {2})'.format(x,y,z)     insert(x,y,z)     assert psycopg2_mock.return_value.cursor.call_count == 1     psycopg2_mock.return_value.cursor.return_value.execute.assert_called_with(sql_query)     assert psycopg2_mock.return_value.commit.call_count == 1     assert psycopg2_mock.return_value.close.call_count == 1 

Comments