簡體   English   中英

如何使用 python 的 unittest mock 構建單元測試用例?

[英]How to build unit test cases using python's unittest mock?

基類具有子類繼承並調用它們的方法。 基類的方法依次調用 util 類中的方法。

util class

@staticmethod
def create_n_insert_into_sql(table_name, data):
    #logic to create table in mysql

@staticmethod
def create_n_insert_into_hive(table_name, data):
   #logic to create hive table

@staticmethod
def create_folder_hdfs(folder_name):
   #logic to create hdfs folder

@staticmethod
def get_data_from_external_source(source_name):
   #logic to fetch data
Base class

import util as u
class BaseImporter:

    __source = None
    __table_name = None
    __folder_name = None

    def __init__(self, folder_name: str, source: str, table: str) -> None:
        self.__source = source
        self.__table_name = table
        self.__folder_name = folder_name


    def run_importer():
        data = u.get_data_from_external_source(self.__source)
        u.create_n_insert_into_sql(self.__table_name, data)
        u.create_n_insert_into_hive(self.__table_name, data)
        u.create_folder_hdfs(self.__folder_name)
Child class

import BaseImporter

class childImporter(BaseImporter):

      def __init__(self, folder_name: str, source: str, table: str):
        super().__init__(
            folder_name='my_folder',
            source='mysql',
            table='accounts',
        )

if __name__ == "__main__":
     importer = childImporter()
     importer.run_importer()

我希望想出一個單元測試套件來測試整個流程,而不僅僅是使用 unittest mock 的單一方法

這是單元測試套件:

util.py :

class Util:
    @staticmethod
    def create_n_insert_into_sql(table_name, data):
        # logic to create table in mysql
        pass

    @staticmethod
    def create_n_insert_into_hive(table_name, data):
        # logic to create hive table
        pass

    @staticmethod
    def create_folder_hdfs(folder_name):
        # logic to create hdfs folder
        pass

    @staticmethod
    def get_data_from_external_source(source_name):
        # logic to fetch data
        pass

base.py

from util import Util as u


class BaseImporter:

    __source = None
    __table_name = None
    __folder_name = None

    def __init__(self, folder_name: str, source: str, table: str) -> None:
        self.__source = source
        self.__table_name = table
        self.__folder_name = folder_name

    def run_importer(self):
        data = u.get_data_from_external_source(self.__source)
        u.create_n_insert_into_sql(self.__table_name, data)
        u.create_n_insert_into_hive(self.__table_name, data)
        u.create_folder_hdfs(self.__folder_name)

child.py

from base import BaseImporter


class ChildImporter(BaseImporter):

    def __init__(self, folder_name: str, source: str, table: str):
        super().__init__(
            folder_name='my_folder',
            source='mysql',
            table='accounts',
        )

test_base.py

import unittest
from base import BaseImporter
from unittest.mock import patch


class TestBaseImporter(unittest.TestCase):
    @patch('base.u', autospec=True)
    def test_run_importer(self, mock_u):
        base_importer = BaseImporter(folder_name='folder_name', source='source', table='table')
        mock_u.get_data_from_external_source.return_value = 'mocked data'
        base_importer.run_importer()
        mock_u.get_data_from_external_source.assert_called_once_with('source')
        mock_u.create_n_insert_into_sql.assert_called_once_with('table', 'mocked data')
        mock_u.create_n_insert_into_hive.assert_called_once_with('table', 'mocked data')
        mock_u.create_folder_hdfs.assert_called_once_with('folder_name')

test_child.py

import unittest
from child import ChildImporter
from base import BaseImporter
from unittest.mock import patch


class TestChildImporter(unittest.TestCase):
    @patch('base.u', autospec=True)
    def test_run_importer(self, mock_u):
        child_importer = ChildImporter(folder_name='folder_name', source='source', table='table')
        mock_u.get_data_from_external_source.return_value = 'mocked data'
        child_importer.run_importer()
        mock_u.get_data_from_external_source.assert_called_once_with('mysql')
        mock_u.create_n_insert_into_sql.assert_called_once_with('accounts', 'mocked data')
        mock_u.create_n_insert_into_hive.assert_called_once_with('accounts', 'mocked data')
        mock_u.create_folder_hdfs.assert_called_once_with('my_folder')
        self.assertIsInstance(child_importer, BaseImporter)

tests.py

import unittest
from test_base import TestBaseImporter
from test_child import TestChildImporter

if __name__ == '__main__':
    test_loader = unittest.TestLoader()

    test_classes_to_run = [TestBaseImporter, TestChildImporter]
    suites_list = []
    for test_class in test_classes_to_run:
        suite = test_loader.loadTestsFromTestCase(test_class)
        suites_list.append(suite)

    big_suite = unittest.TestSuite(suites_list)
    unittest.TextTestRunner().run(big_suite)

帶有覆蓋率報告的單元測試結果:

(venv) ☁  python-codelab [master] ⚡  coverage run /Users/ldu020/workspace/github.com/mrdulin/python-codelab/src/stackoverflow/56339991/tests.py && coverage report -m                                       
..
----------------------------------------------------------------------
Ran 2 tests in 0.027s

OK
Name                                       Stmts   Miss  Cover   Missing
------------------------------------------------------------------------
src/stackoverflow/56339991/base.py            14      0   100%
src/stackoverflow/56339991/child.py            4      0   100%
src/stackoverflow/56339991/test_base.py       12      0   100%
src/stackoverflow/56339991/test_child.py      14      0   100%
src/stackoverflow/56339991/tests.py           12      0   100%
src/stackoverflow/56339991/util.py             9      4    56%   5, 10, 15, 20
------------------------------------------------------------------------
TOTAL                                         65      4    94%

源代碼: https : //github.com/mrdulin/python-codelab/tree/master/src/stackoverflow/56339991

暫無
暫無

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

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