2017-01-10 5 views
1

Newby для python здесь. В моем классе используется соединение с базой данных для переноса некоторых функций. Я придумал несколько базовых примеров. Для более сложной библиотеки, с которой я работаю, я не могу найти близких примеров издевательств по подключению к базе данных. В шахтах,Python Mocking db connection/unknown type in unit test

class DBSAccess(): 
    def __init__(self, db_con): 
     self.db_con = db_con 

    def get_db_perm(self, target_user): 
     ## this is where I start having trouble 
     with self.db_con.cursor() as cursor: 
      cursor.execute("SELECT CAST(sum(maxperm) AS bigint) \ 
      FROM dbc.diskspace \ 
      WHERE databasename = '%s' \ 
      GROUP BY databasename" % (target_user)) 

      res = cursor.fetchone() 
      if res is not None: 
       return res[0] 
      else: 
       msg = target_user + " does not exist" 
       return msg 

где db_con является teradata.UdaExec возвращается на соединении

udaExec = teradata.UdaExec (appName="whatever", version="1.0", logConsole=True) 
db_con = udaExec.connect(method="odbc", system='my_sys', username='my_name', password='my_pswd') 
dbc_instance = tdtestpy.DBSaccess (db_con) 

Так что для моего теста, чтобы не использовать какую-либо реальную связь я издеваться некоторыми вещами. Я попробовал эту комбинацию:

class DBAccessTest(unittest.TestCase): 
    def test_get_db_free_perm_expects_500(self): 
    uda_exec = mock.Mock(spec=teradata.UdaExec) 
    db_con = MagicMock(return_value=None) 
    db_con.cursor.fetchone.return_value = [500] 
    uda_exec.connect.return_value = db_con 
    self.dbc_instance = DBSAccess(db_con) 
    self.assertEqual(self.dbc_instance.get_db_free_perm("dbc"), 500) 

, но мой результат перепутались, потому что fetchone возвращается издеваться, а не список [500] один пункт, который я ожидал:

AssertionError: <MagicMock name='mock.connect().cursor().[54 chars]312'> != 500 

Я нашел несколько примеров где есть «с блоком» для тестирования операционной системы, но ничего с базой данных. Кроме того, я не знаю, какой тип данных является db_con.cursor, поэтому я не могу точно это точно сказать - я думаю, что курсор находится в UdaExecConnection.cursor(), найденном по адресу Teradata/PyTd.

Мне нужно знать, как издеваться над ответом, который позволит мне проверить логику в моем методе.

+0

Часть проблемы заключается в том, что вы насмешливый '.attribute.method.return_value' вместо' .method () .method.return_value' – jonrsharpe

+0

Я не думал об этом. Благодарю. Я не уверен, как превратить курсор в издевательский метод. Вы говорили об этой линии? '' 'db_con.cursor.fetchone.return_value = [500]' '' –

ответ

7

Источник вашей проблемы в следующей строке:

with self.db_con.cursor() as cursor: 

with линии вызывает __enter__ method, которые генерируют в вашем случае новый макет.

Решение заключается в mock __enter__ method:

db_con.cursor.return_value.__enter__.return_value = cursor 

Ваши тесты:

class DBAccessTest(unittest.TestCase): 
    def test_get_db_free_perm_expects_500(self): 
     db_con = MagicMock(UdaExecConnection) 
     cursor = MagicMock(UdaExecCursor) 
     cursor.fetchone.return_value = [500] 
     db_con.cursor.return_value.__enter__.return_value = cursor 
     self.dbc_instance = DBSAccess(db_con) 
     self.assertEqual(self.dbc_instance.get_db_perm("dbc"), 500) 

    def test_get_db_free_perm_expects_None(self): 
     db_con = MagicMock(UdaExecConnection) 
     cursor = MagicMock(UdaExecCursor) 
     cursor.fetchone.return_value = None 
     db_con.cursor.return_value.__enter__.return_value = cursor 
     self.dbc_instance = DBSAccess(db_con) 
     self.assertEqual(self.dbc_instance.get_db_perm("dbc"), "dbc does not exist") 
+0

Извините, мой импорт не работает с этими изменениями. Можете ли вы включить операции импорта? '' 'ERROR: test_get_db_free_perm_expects_500 (__main __. DBAccessTest) ------------------------------------- --------------------------------- Traceback (последний звонок последний): Файл «/ home/dm186069/проекты/tdtestpy/tdtestpy/UnitTest/питон/test_dbaccess_class.py», строка 19, в test_get_db_free_perm_expects_500 db_con = MagicMock (UdaExecConnection) NameError: имя 'UdaExecConnection' не defined''' –

+0

Nevermind. pycharm исправил это для меня. –