복붙노트

[PYTHON] except 블록을 테스트하기 위해 예외를 발생시키는 함수 조롱

PYTHON

except 블록을 테스트하기 위해 예외를 발생시키는 함수 조롱

다른 함수 (bar)를 호출하는 함수 (foo)가 있습니다. bar ()를 호출하면 HttpError가 발생하고, 상태 코드가 404이면 특별히 처리하려고합니다. 그렇지 않으면 다시 올립니다.

bar ()에 대한 호출을 조롱하면서이 foo 함수를 중심으로 단위 테스트를 작성하려고합니다. 불행히도, 나는 bar ()에 대한 조롱당한 호출을 except 블록에 잡힌 Exception을 발생시킬 수 없다.

내 문제를 설명하는 코드는 다음과 같습니다.

import unittest
import mock
from apiclient.errors import HttpError


class FooTests(unittest.TestCase):
    @mock.patch('my_tests.bar')
    def test_foo_shouldReturnResultOfBar_whenBarSucceeds(self, barMock):
        barMock.return_value = True
        result = foo()
        self.assertTrue(result)  # passes

    @mock.patch('my_tests.bar')
    def test_foo_shouldReturnNone_whenBarRaiseHttpError404(self, barMock):
        barMock.side_effect = HttpError(mock.Mock(return_value={'status': 404}), 'not found')
        result = foo()
        self.assertIsNone(result)  # fails, test raises HttpError

    @mock.patch('my_tests.bar')
    def test_foo_shouldRaiseHttpError_whenBarRaiseHttpErrorNot404(self, barMock):
        barMock.side_effect = HttpError(mock.Mock(return_value={'status': 500}), 'error')
        with self.assertRaises(HttpError):  # passes
            foo()

def foo():
    try:
        result = bar()
        return result
    except HttpError as error:
        if error.resp.status == 404:
            print '404 - %s' % error.message
            return None
        raise

def bar():
    raise NotImplementedError()

Mock 문서를 따라 가면 Mock 인스턴스의 side_effect를 Exception 클래스로 설정해야 조롱 된 함수가 오류를 발생시킵니다.

나는 또한 다른 관련 StackOverflow Q & As를 살펴 보았고, 그들이하는 일과 같은 일을하고있는 것처럼 보였다. 그리고 예외는 그들의 모의에 의해 제기되었다.

barMock의 side_effect를 설정하면 예상되는 Exception이 발생하지 않는 이유는 무엇입니까? 이상한 일을하고 있다면, 예외 블록에서 로직을 테스트하는 방법을 어떻게해야합니까?

해결법

  1. ==============================

    1.귀하의 모의가 예외를 잘 일으키고 있지만 error.resp.status 값이 누락되었습니다. return_value를 사용하는 대신 Mock에게 상태가 속성임을 알려주십시오.

    귀하의 모의가 예외를 잘 일으키고 있지만 error.resp.status 값이 누락되었습니다. return_value를 사용하는 대신 Mock에게 상태가 속성임을 알려주십시오.

    barMock.side_effect = HttpError(mock.Mock(status=404), 'not found')
    

    Mock ()에 대한 추가 키워드 인수는 결과 객체의 속성으로 설정됩니다.

    나는 foo와 bar 정의를 HttpError 클래스에 추가 된 my_tests 모듈에 넣어서 사용할 수도 있으므로 테스트를 성공적으로 수행 할 수 있습니다.

    >>> from my_tests import foo, HttpError
    >>> import mock
    >>> with mock.patch('my_tests.bar') as barMock:
    ...     barMock.side_effect = HttpError(mock.Mock(status=404), 'not found')
    ...     result = my_test.foo()
    ... 
    404 - 
    >>> result is None
    True
    

    print '404 - % s'% error.message 행을 볼 수 있지만, 대신 error.content를 사용하고 싶다고 생각합니다. 이는 HttpError ()가 두 번째 인수에서 설정하는 속성입니다.

  2. from https://stackoverflow.com/questions/28305406/mocking-a-function-to-raise-an-exception-to-test-an-except-block by cc-by-sa and MIT license