<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python 中 Mock 到底該怎么玩?一篇文章告訴你(超全)

          共 4015字,需瀏覽 9分鐘

           ·

          2021-02-06 08:52


          ↑?關(guān)注 + 星標(biāo)?,每天學(xué)Python新技能

          后臺(tái)回復(fù)【大禮包】送你Python自學(xué)大禮包




          1. 前言

          微服務(wù)架構(gòu)下,由于各類(lèi)服務(wù)開(kāi)發(fā)進(jìn)度的不一致,導(dǎo)致聯(lián)調(diào)工作經(jīng)常會(huì)存在不確定性,進(jìn)而導(dǎo)致項(xiàng)目延期

          在實(shí)際工作中,為了保證項(xiàng)目進(jìn)度,我們經(jīng)常需要針對(duì)部分未完成模塊及不穩(wěn)定模塊采用?Mock 方式,以驗(yàn)證已開(kāi)發(fā)完的模塊

          本篇文章將介紹 Python 實(shí)現(xiàn) Mock 的幾種常見(jiàn)方式

          2. Mock 介紹

          Mock 測(cè)試:在測(cè)試驗(yàn)證過(guò)程中,對(duì)于那些尚未完成或不穩(wěn)定的對(duì)象,用一個(gè)虛擬對(duì)象來(lái)替代,以便測(cè)試的測(cè)試方法

          因此,這個(gè)虛擬的對(duì)象是 Mock 對(duì)象,Mock 對(duì)象是真實(shí)對(duì)象在調(diào)試期間的代替品

          它的優(yōu)勢(shì)包含:

          • 前、后端并行開(kāi)發(fā)

          • 模擬無(wú)法訪問(wèn)的資源

          • 隔離系統(tǒng),避免臟數(shù)據(jù)干擾測(cè)試結(jié)果

          3.1 mock

          在 Python 3.3 之前使用 mock,需要先安裝依賴(lài)

          #?安裝mock依賴(lài)
          pip3?install?mock

          項(xiàng)目地址:

          https://github.com/testing-cabal/mock

          假設(shè) Product 類(lèi)中有 2 個(gè)方法

          • get_product_status_by_id

          • buy_product

          其中,get_product_status_by_id 方法還沒(méi)有實(shí)現(xiàn);buy_product 方法依賴(lài)于 get_product_status_by_id 方法的返回值
          #?product_impl.py

          class?Product(object):

          ????def?__init__(self):
          ????????pass

          ????def?get_product_status_by_id(self,?product_id):
          ????????"""
          ????????通過(guò)商品id獲取產(chǎn)品信息(Mock)
          ????????:return:
          ????????"""

          ????????#?待實(shí)現(xiàn)查詢數(shù)據(jù)庫(kù)的業(yè)務(wù)邏輯
          ????????pass

          ????def?buy_product(self,?product_id):
          ????????"""
          ????????購(gòu)買(mǎi)產(chǎn)品(真實(shí)邏輯)
          ????????:return:
          ????????"""

          ????????#?產(chǎn)品信息
          ????????#?{"id":1,"name":"蘋(píng)果","num":23}
          ????????product?=?self.get_product_status_by_id(product_id)

          ????????if?product.get("num")?>=?1:
          ????????????result?=?{"status":?0,?"msg":?"購(gòu)買(mǎi)成功!"}
          ????????else:
          ????????????result?=?{"status":?1,?"msg":?"購(gòu)買(mǎi)失敗,庫(kù)存不足!"}

          ????????return?result
          Mock 的步驟如下:
          • 導(dǎo)入使用 mock 中的 patch 方法

          • 作為測(cè)試方法的裝飾器,對(duì) get_product_status_by_id 方法進(jìn)行 Mock,方法參數(shù)為 Mock 對(duì)象

          • 測(cè)試方法中,對(duì)該 Mock 對(duì)象設(shè)置一個(gè)返回值

          • 調(diào)用并斷言

          from?mock?import?patch
          from?mock_.product_impl?import?Product

          @patch('mock_.product_impl.Product.get_product_status_by_id')
          def?test_succuse(mock_get_product_status_by_id):
          ????#?Mock方法,指定一個(gè)返回值
          ????mock_get_product_status_by_id.return_value?=?{"id":?1,?"name":?"蘋(píng)果",?"num":?23}

          ????product?=?Product()

          ????assert?product.buy_product(1).get("status")?==?0

          需要注意的是,Mock?此方法的時(shí)候,必須制定該方法的完整路徑

          使用?@patch.object?同樣能完成 Mock,不同的是,@patch.object 包含 2 個(gè)參數(shù)

          第一個(gè)參數(shù)為該方法所在的類(lèi);第二個(gè)參數(shù)為方法名

          from?mock?import?patch

          from?mock_.product_impl?import?Product

          #?Mock一個(gè)方法
          #[email protected]:對(duì)象、方法名
          @patch.object(Product,?'get_product_status_by_id')
          def?test_succuse(mock_get_product_status_by_id):
          ????#?Mock方法,指定一個(gè)返回值
          ????mock_get_product_status_by_id.return_value?=?{"id":?1,?"name":?"蘋(píng)果",?"num":?23}

          ????product?=?Product()

          ????assert?product.buy_product(1).get("status")?==?0

          3.2?unittest.mock

          Python 3.3 之后,mock 作為標(biāo)準(zhǔn)庫(kù),已經(jīng)內(nèi)置到 unittest 中了

          還是以 3.1 的場(chǎng)景為例,使用 unittest 編寫(xiě)一個(gè)測(cè)試用例

          Mock 步驟如下:

          • 導(dǎo)入 unittest 框架中的 mock 文件

          • 實(shí)例化 Product 對(duì)象

          • mock.Mock(return_value=*) 方法

            對(duì) get_product_status_by_id 方法進(jìn)行 Mock

          • 調(diào)用并斷言

          import?unittest
          from?unittest?import?mock

          from?unittest_mock.product_impl?import?Product

          class?TestProduct(unittest.TestCase):

          ????def?test_success(self):
          ????????#?成功結(jié)果
          ????????mock_success_value?=?{"id":?1,?"name":?"蘋(píng)果",?"num":?23}

          ????????product?=?Product()

          ????????product.get_product_status_by_id?=?mock.Mock(return_value=mock_success_value)

          ????????#?調(diào)用實(shí)際函數(shù)
          ????????assert?product.buy_product(1).get("status")?==?0

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

          3.3?pytest.mock

          相比 unittest,pytest 由于強(qiáng)大的插件支持,用戶群體可能更大!

          如果項(xiàng)目本身使用的框架是 pytest,則 Mock 更建議使用?pytest-mock 這個(gè)插件

          #?pytest依賴(lài)
          pip3?install?pytest

          Mock 步驟如下:

          • 使用 pytest 編寫(xiě)測(cè)試方法,參數(shù)為?mocker

          • 實(shí)例化 Product 對(duì)象

          • 使用 mocker.patch()?方法對(duì)?get_product_status_by_id 方法進(jìn)行 Mock,并設(shè)置返回值

          • 調(diào)用并斷言

          import?pytest

          from?pytest_mock_.product_impl?import?Product

          def?test_buy_product_success(mocker):
          ????"""
          ????購(gòu)買(mǎi)成功Mock
          ????:param?mocker:
          ????:return:
          ????"""

          ????#?實(shí)例化一個(gè)產(chǎn)品對(duì)象
          ????product?=?Product()

          ????#?對(duì)Product中的方法的返回值進(jìn)行Mock
          ????mock_value?=?{"id":?1,?"name":?"蘋(píng)果",?"num":?23}

          ????#?Mock方法
          ????#?注意:需要指定方法的完整路徑
          ????#?mocker.patch?的第一個(gè)參數(shù)必須是模擬對(duì)象的具體路徑,第二個(gè)參數(shù)用來(lái)指定返回值
          ????product.get_product_status_by_id?=?mocker.patch("product_impl.Product.get_product_status_by_id",
          ????????????????????????????????????????????????????return_value=mock_value)

          ????#?調(diào)用購(gòu)買(mǎi)產(chǎn)品的方法
          ????result?=?product.buy_product(1)

          ????assert?result.get("status")?==?0

          需要注意的是,mocker.patch 方法第一個(gè)參數(shù)必須是 Mock 對(duì)象的完整路徑

          4. 最后

          文中對(duì) Python 中常見(jiàn)的 Mock 方案進(jìn)行了講解,實(shí)際應(yīng)用中,建議根據(jù)項(xiàng)目實(shí)際情況進(jìn)行選型。

          見(jiàn)面禮


          碼加我微信備注「三劍客」送你上圖三本Python入門(mén)電子書(shū)?


          推薦閱讀


          1. 熬夜一周整理我的數(shù)據(jù)分析學(xué)習(xí)資源

          2. 為什么建議大家使用 Linux 開(kāi)發(fā)?爽(外加七個(gè)感嘆號(hào))

          3. 我為什么拋棄Windows,入坑MacBook

          4. 自學(xué)Python3年,我終于做了這個(gè)決定....

          點(diǎn)分享
          點(diǎn)收藏
          點(diǎn)點(diǎn)贊
          點(diǎn)在看
          瀏覽 44
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日嫩B视频 | 国产福利乱伦 | 九一一三级片 | 最近日韩中文字幕高清视频 | 六月色婷婷激情综合 |