Как правильно обработать ошибку pyodbc в операторе try-except

#python #python-3.x #unit-testing #error-handling #pyodbc

#python #python-3.x #модульное тестирование #обработка ошибок #pyodbc

Вопрос:

Я хочу знать, что я обрабатываю исключение, которое возникает только тогда, когда путь к моей базе данных неверен, и правильное возникновение только этой ошибки отражается на прохождении или сбое моего теста для функции. В настоящее время мой модульный тест проходит, когда любая ошибка включена в предложение except как err .

Я подозреваю, что я неправильно создаю оператор try-except, чтобы перехватить правильную ошибку. С помощью pyodbc я специально пытаюсь перехватить ошибку с именем ‘pyodbc.Error’, но в настоящее время все ошибки приводят к прохождению теста.

Я хочу, чтобы тест завершился неудачей, если только возникающая ошибка не является ошибкой, указанной в предложении except . Я не хочу, чтобы «перехватывать все» попытки, кроме.

 def get_database():
    try:
        conn = pyodbc.connect(
            r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};'
            r'DBQ=M:PathToDatabaseMy_Database.accdb;'
        )
        return conn
    except pyodbc.Error as err: # Only error I wanted passed for the test!
        raise err

@mock.patch('directory1.script1.pyodbc.connect')
def test_invalid_path_to_database(self, mock_conn):
    mock_conn.side_effect = pyodbc.Error

    # Passes no matter what exception is included in except clause!
    self.assertRaises(pyodbc.Error, get_database)  
  

Ответ №1:

Вот рабочий пример, который, похоже, улавливает pyodbc.Error ошибки non. Можете ли вы уточнить, что вы пытаетесь сделать?

 import pyodbc
import unittest
import mock

def get_database():
    try:
        conn = pyodbc.connect(
            r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};'
            r'DBQ=M:PathToDatabaseMy_Database.accdb;'
        )
        return conn
    except pyodbc.Error as err: # Only error I wanted passed for the test!
        raise ValueError('Non pyodbc error')

class Test(unittest.TestCase):
    @mock.patch('pyodbc.connect')
    def test_invalid_path_to_database(self, mock_conn):
        mock_conn.side_effect = pyodbc.Error

        self.assertRaises(pyodbc.Error, get_database)

if __name__ == '__main__':
    unittest.main()
  

С выводом

 Traceback (most recent call last):
  File "/Users/henry/projects/stack/.venv/lib/python3.7/site-packages/mock/mock.py", line 1305, in patched
    return func(*args, **keywargs)
  File "example.py", line 21, in test_invalid_path_to_database
    self.assertRaises(pyodbc.Error, get_database)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 743, in assertRaises
    return context.handle('assertRaises', args, kwargs)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 178, in handle
    callable_obj(*args, **kwargs)
  File "example.py", line 13, in get_database
    raise ValueError('Non pyodbc error')
ValueError: Non pyodbc error

----------------------------------------------------------------------
Ran 1 test in 0.002s
  

Комментарии:

1. Эй, извините, если я был неясен! Я хочу перехватить pyodbc.Error, когда базовый путь неверен (т.Е. База данных отсутствует, какая-то часть пути неверна и т. Д.). Затем я хочу проверить эту ошибку, и возникает только эта ошибка. Я только включил повторное повышение само по себе в свой пример, но реально я бы добавил больше кода для его обработки (т.Е. Ведения журнала), но оставил его как есть для простоты. Прямо сейчас тест проходит, независимо от того, какую ошибку я пытаюсь поймать, но я хочу, чтобы он прошел, только если был вызван pyodbc.Error