簡體   English   中英

模擬函數以引發異常以測試except塊

[英]Mocking a function to raise an Exception to test an except block

我有一個函數( 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()

我遵循Mock文檔 ,它說你應該將Mock實例的side_effect設置為Exception類,以使Mock函數引發錯誤。

我還看了一些其他相關的StackOverflow Q&As,看起來我正在做他們正在做的同樣的事情,並且他們的模擬引發了Exception。

為什么設置side_effectbarMock不會導致引發預期的Exception 如果我做了一些奇怪的事情,我該如何在我的except塊中測試邏輯呢?

你的模擬正好提升異常,但缺少error.resp.status值。 而不是使用return_value ,只需告訴Mock status是一個屬性:

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 line run,但我認為你想在那里使用error.content ; 這是HttpError()從第二個參數設置的屬性,無論如何。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM