Python mock

官方文檔 : https://docs.python.org/dev/library/unittest.mock.html

Mock

Mock類庫(kù)是一個(gè)專門用于在unittest過程中制作(偽造)和修改(篡改)測(cè)試對(duì)象的類庫(kù)达吞,制作和修改的目的是避免這些對(duì)象在單元測(cè)試過程中依賴外部資源(網(wǎng)絡(luò)資源,數(shù)據(jù)庫(kù)連接,其它服務(wù)以及耗時(shí)過長(zhǎng)等).

安裝

Python 2.7中沒有集成mock庫(kù),Python3中的unittest中集成了mock庫(kù).

Python 2.7環(huán)境下pip安裝:

$ pip install mock

快速使用

>>> from mock import MagicMock      #MagicMock為Mock的子類
>>> thing = ProductionClass()
>>> thing.method = MagicMock(return_value=3)
#指定返回3
>>> thing.method(3, 4, 5, key='value')
3
>>> thing.method.assert_called_with(3, 4, 5, key='value')
#斷言輸入是否為3,4,5,key='value',否則報(bào)錯(cuò)

示例

#module.py

class Count():

    def add(self, a, b):
        return a + b

測(cè)試用例:

from unittest import mock
import unittest
from module import Count


class MockDemo(unittest.TestCase):

    def test_add(self):
        count = Count()
        count.add = mock.Mock(return_value=13, side_effect=count.add)
        result = count.add(8, 8)
        print(result)
        count.add.assert_called_with(8, 8)
        self.assertEqual(result, 16)

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

count.add = mock.Mock(return_value=13, side_effect=count.add)

side_effect參數(shù)和return_value是相反的芽世。它給mock分配了可替換的結(jié)果语御,覆蓋了return_value遂跟。簡(jiǎn)單的說户辱,一個(gè)模擬工廠調(diào)用將返回side_effect值咒钟,而不是return_value卢肃。

所以疲迂,設(shè)置side_effect參數(shù)為Count類add()方法,那么return_value的作用失效莫湘。

測(cè)試依賴

例如尤蒿,我們要測(cè)試A模塊,然后A模塊依賴于B模塊的調(diào)用幅垮。但是优质,由于B模塊的改變,導(dǎo)致了A模塊返回結(jié)果的改變军洼,從而使A模塊的測(cè)試用例失敗巩螃。其實(shí),對(duì)于A模塊匕争,以及A模塊的用例來說避乏,并沒有變化,不應(yīng)該失敗才對(duì)甘桑。

通過mock模擬掉影響A模塊的部分(B模塊)拍皮。至于mock掉的部分(B模塊)應(yīng)該由其它用例來測(cè)試。

# function.py
def add_and_multiply(x, y):
    addition = x + y
    multiple = multiply(x, y)
    return (addition, multiple)


def multiply(x, y):
    return x * y

然后跑杭,針對(duì) add_and_multiply()函數(shù)編寫測(cè)試用例铆帽。func_test.py

import unittest
import function


class MyTestCase(unittest.TestCase):

    def test_add_and_multiply(self):
        x = 3
        y = 5
        addition, multiple = function.add_and_multiply(x, y)
        self.assertEqual(8, addition)
        self.assertEqual(15, multiple)


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

add_and_multiply()函數(shù)依賴了multiply()函數(shù)的返回值。如果這個(gè)時(shí)候修改multiply()函數(shù)的代碼德谅。

def multiply(x, y):
    return x * y + 3

python3 func_test.py
F
======================================================================
FAIL: test_add_and_multiply (main.MyTestCase)
Traceback (most recent call last):
File "fun_test.py", line 19, in test_add_and_multiply
self.assertEqual(15, multiple)
AssertionError: 15 != 18
Ran 1 test in 0.000s
FAILED (failures=1)

測(cè)試用例運(yùn)行失敗了爹橱,然而,add_and_multiply()函數(shù)以及它的測(cè)試用例并沒有做任何修改窄做,罪魁禍?zhǔn)资莔ultiply()函數(shù)引起的愧驱,我們應(yīng)該把 multiply()函數(shù)mock掉。

import unittest
from unittest.mock import patch
import function


class MyTestCase(unittest.TestCase):

    @patch("function.multiply")
    def test_add_and_multiply2(self, mock_multiply):
        x = 3
        y = 5
        mock_multiply.return_value = 15
        addition, multiple = function.add_and_multiply(x, y)
        mock_multiply.assert_called_once_with(3, 5)

        self.assertEqual(8, addition)
        self.assertEqual(15, multiple)


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


@patch("function.multiply")

patch()裝飾/上下文管理器可以很容易地模擬類或?qū)ο笤谀K測(cè)試椭盏。在測(cè)試過程中组砚,您指定的對(duì)象將被替換為一個(gè)模擬(或其他對(duì)象),并在測(cè)試結(jié)束時(shí)還原掏颊。

這里模擬function.py文件中multiply()函數(shù)糟红。

def test_add_and_multiply2(self, mock_multiply):

在定義測(cè)試用例中,將mock的multiply()函數(shù)(對(duì)象)重命名為 mock_multiply對(duì)象。

mock_multiply.return_value = 15

設(shè)定mock_multiply對(duì)象的返回值為固定的15盆偿。

ock_multiply.assert_called_once_with(3, 5)

檢查ock_multiply方法的參數(shù)是否正確柒爸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市陈肛,隨后出現(xiàn)的幾起案子揍鸟,更是在濱河造成了極大的恐慌,老刑警劉巖句旱,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阳藻,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡谈撒,警方通過查閱死者的電腦和手機(jī)腥泥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啃匿,“玉大人蛔外,你說我怎么就攤上這事∷萜梗” “怎么了夹厌?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)裆悄。 經(jīng)常有香客問我矛纹,道長(zhǎng),這世上最難降的妖魔是什么光稼? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任或南,我火速辦了婚禮,結(jié)果婚禮上艾君,老公的妹妹穿的比我還像新娘采够。我一直安慰自己,他們只是感情好冰垄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布蹬癌。 她就那樣靜靜地躺著,像睡著了一般播演。 火紅的嫁衣襯著肌膚如雪冀瓦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天写烤,我揣著相機(jī)與錄音,去河邊找鬼拾徙。 笑死洲炊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播暂衡,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼询微,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了狂巢?” 一聲冷哼從身側(cè)響起撑毛,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎唧领,沒想到半個(gè)月后藻雌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡斩个,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年胯杭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片受啥。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡做个,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出滚局,到底是詐尸還是另有隱情居暖,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布藤肢,位于F島的核電站太闺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谤草。R本人自食惡果不足惜跟束,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丑孩。 院中可真熱鬧冀宴,春花似錦、人聲如沸温学。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)仗岖。三九已至逃延,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間轧拄,已是汗流浹背揽祥。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留檩电,地道東北人拄丰。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓府树,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親料按。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奄侠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Startup 單元測(cè)試的核心價(jià)值在于兩點(diǎn): 更加精確地定義某段代碼的作用,從而使代碼的耦合性更低 避免程序員寫出...
    wuwenxiang閱讀 10,083評(píng)論 1 27
  • 單元測(cè)試 什么是單元 單元測(cè)試(unit testing)载矿,是指對(duì)軟件中的最小可測(cè)試單元(一個(gè)模塊垄潮、一個(gè)函數(shù)或者一...
    PPMac閱讀 6,497評(píng)論 0 19
  • 最近做發(fā)短信的service的時(shí)候,與短信相關(guān)的測(cè)試需要mock闷盔,于是碰到以下問題弯洗。例如有三個(gè)模塊a和b和test...
    doyoubi閱讀 1,202評(píng)論 0 3
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)馁筐,斷路器涂召,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 今日兩市再次低開,創(chuàng)業(yè)板開盤即跌破了前期的低點(diǎn)敏沉,創(chuàng)出了兩年以來的新低果正,隨后就是一路的震蕩,至收盤盟迟,滬指收于3093...
    股海蒼穹閱讀 140評(píng)論 0 0