簡體   English   中英

如何為python單元測試提供模擬類方法?

[英]How to supply a mock class method for python unit test?

假設我有一堂這樣的課。

class SomeProductionProcess(CustomCachedSingleTon):
    
    @classmethod
    def loaddata(cls):
        """
        Uses an iterator over a large file in Production for the Data pipeline.
        """
        pass

現在在測試時我想更改loaddata()方法中的邏輯。 這將是一個不處理大數據的簡單自定義邏輯。

我們如何在測試時使用 Python Mock UnitTest 框架提供loaddata()自定義實現?

這是使用模擬的簡單方法

import mock


def new_loaddata(cls, *args, **kwargs):
    # Your custom testing override
    return 1


def test_SomeProductionProcess():
    with mock.patch.object(SomeProductionProcess, 'loaddata', new=new_loaddata):
        obj = SomeProductionProcess()
        obj.loaddata()  # This will call your mock method

如果可以,我建議使用pytest而不是unittest模塊。 它使您的測試代碼更清晰,並減少了您通過unittest.TestCase樣式測試獲得的大量樣板。

要輕松模擬具有結構化 return_value 的類方法,可以使用unittest.mock.Mock

from unittest.mock import Mock

mockObject = SomeProductionProcess
mockObject.loaddata = Mock(return_value=True)

編輯:

由於您想使用自定義實現來模擬方法,因此您可以創建自定義模擬方法對象並在測試運行時換出原始方法。

def custom_method(*args, **kwargs):
    # do custom implementation

SomeProductionProcess.loaddata = custom_method

假設您有一個名為awesome.py的模塊,其中包含:

import time

class SomeProductionProcess(CustomCachedSingleTon):

    def loaddata(self):
        time.sleep(30) # simulating a long running process
        return 2

然后,您模擬loaddata可能如下所示:

import unittest

import awesome # your application module


class TestSomeProductionProcess(unittest.TestCase):
    """Example of direct monkey patching"""

    def test_loaddata(self):
        some_prod_proc = awesome.SomeProductionProcess()
        some_prod_proc.loaddata = lambda x: 2 # will return 2 every time called
        output = some_prod_proc.loaddata()
        expected = 2

        self.assertEqual(output, expected)

或者它看起來像這樣:

import unittest
from mock import patch

import awesome # your application module

class TestSomeProductionProcess(unittest.TestCase):
    """Example of using the mock.patch function"""

    @patch.object(awesome.SomeProductionProcess, 'loaddata')
    def test_loaddata(self, fake_loaddata):
        fake_loaddata.return_value = 2
        some_prod_proc = awesome.SomeProductionProcess()

        output = some_prod_proc.loaddata()
        expected = 2

        self.assertEqual(output, expected)

現在,當您運行測試時,對於這些測試用例, loaddata不會花費 30 秒。

暫無
暫無

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

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