Как вы проверяете, что функция выдает исключение?

У меня есть функция ниже, и я хочу написать модульный тест, чтобы проверить, ловит ли мой код ConnectionError, используя фиктивную библиотеку.

def get_foo():
    try:
        return requests.get("http://www.bongani.com")
    except requests.exceptions.ConnectionError:
        print("Error")

Что я имею:

import unittest
import mock


class MyTestCase(unittest.TestCase):
    @mock.patch('requests.get')
    def test_foo(self, mock_requests_get):
        mock_requests_get.side_effect = requests.exceptions.ConnectionError()
        with self.assertRaises(requests.exceptions.ConnectionError):
            get_foo()

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

Я получаю эту ошибку:

Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 1305 , in patched
  return func(*args, **keywargs)
File "<ipython-input-24-15266e4f708a>", , in test_foo
  get_foo()
AssertionError: ConnectionError not raised

Я хочу издеваться над строкой return requests.get("http://www.bongani.com"), чтобы она вызывала исключение при вызове


person Bongani Sibanda    schedule 08.08.2017    source источник


Ответы (2)


Исключение не пузырится (т.е. подавляется), потому что вы его поймали и потом не поднимали повторно. В свою очередь, ваши модульные тесты потерпят неудачу, потому что вы проверяете, что ваша функция вызывает это исключение, в то время как подавляет его.

Вы либо изменяете функцию, либо модульный тест функции в зависимости от желаемого поведения.

Предполагая, что тесты верны, ваша функция должна повторно вызвать исключение следующим образом:

def get_foo():
    try:
        return requests.get("http://www.bongani.com")
    except requests.exceptions.ConnectionError:
        print("Error")
        raise  # <---------------- add this line

Другой сценарий, функция правильная, а тесты неправильные. Вы исправляете свои тесты, чтобы они выглядели так:

class MyTestCase(unittest.TestCase):
    @mock.patch('requests.get')
    def test_foo(self, mock_requests_get):
        mock_requests_get.side_effect = requests.exceptions.ConnectionError()
        self.assertIsNone(get_foo())  # <----- no more assertRaises
person dopstar    schedule 12.08.2017
comment
Я выбрал сценарий 2. Спасибо, что заставили меня увидеть мою ошибку. - person Bongani Sibanda; 05.02.2018

Убедитесь, что вы исправили правильный путь

@mock.patch('path.to.get_foo.requests.get')

Вы не хотите создавать экземпляр исключения.

mock_requests_get.side_effect = requests.exceptions.ConnectionError
person Dan    schedule 08.08.2017
comment
Все еще получаю те же результаты. - person Bongani Sibanda; 08.08.2017