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


119

내가 함수 (이 foo또 다른 함수를 호출) ( bar). 호출이 경우 bar()을 제기 HttpError상태 코드는 달리 재 인상, 404 인 경우, 내가 특별히 그것을 처리 할.

foo함수에 대한 일부 단위 테스트를 작성 하여 bar(). 불행히도 bar()except블록에서 잡은 예외를 발생 시키는 모의 호출을 얻을 수 없습니다 .

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

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()

나는 다음 모의 문서 는 설정해야합니다 말 side_effectMock에 인스턴스를 Exception조롱 기능 인상을 오류를 가지고 클래스를.

나는 또한 다른 관련 StackOverflow Q & A를 살펴 보았고, 그들이 모의에 의해 발생하는 예외와 똑같은 일을하고있는 것처럼 보입니다.

왜 설정되어 side_effectbarMock예상 원인이되지 Exception제기 할 수는? 내가 이상한 일을하고 있다면 내 except블록 에서 로직 테스트를 어떻게해야 합니까?


예외 발생하고 있다고 확신하지만 resp.status코드를 어떻게 설정하는지 잘 모르겠습니다 . 어디 HTTPError에서 왔습니까?
Martijn Pieters

@MartijnPieters HttpError는 GAE에서 사용하는 Google의 apiclientlib에 정의 된 클래스 입니다. 그것은 것 __init__params 객체를 파라미터로 정의 (resp, content)내가 응답을 모의 인스턴스를 만들려고 그래서 적절한 상태 코드를 지정하여,.
Jesse Webb

맞습니다 . 이 클래스입니다 . 하지만 return_value그때 는 사용자가 필요하지 않습니다 . 호출resp 되지 않습니다 .
Martijn Pieters

1
사용하지 않고 코드를 다시 HttpError시도하고 대신 일반 Exception인스턴스 를 사용해 보았습니다 . 이것은 완벽하게 작동합니다. 즉 , 응답을위한 인스턴스를 HttpError만드는 방법과 관련 하여 인스턴스를 구성하는 방법과 관련이 있어야합니다 Mock.
Jesse Webb

답변:


141

당신의 모의는 예외를 잘 일으키고 있지만 error.resp.status값이 없습니다. 을 사용하는 대신 속성 이라고 return_value말하면됩니다 .Mockstatus

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

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

나는 당신 foobar정의를 my_tests모듈에 넣고 HttpError클래스에 추가 하여 나도 사용할 수 있도록했으며 테스트를 성공적으로 실행할 수 있습니다.

>>> 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
side_effect핵심 부분입니다
다니엘 버틀러
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.