簡體   English   中英

如何在Python單元測試中模擬類?

[英]How do I mock a class in a Python unit test?

我有一堂課:

class A:
    __init__(self):
        self.b = B()

   def is_authorized(self)
      name = self.b.get_name()

      if name == 'admin':
          return True
      else:
          return False

我想編寫一個單元測試來測試is_authorized方法。 問題在於,它需要一個B類的實例,由於需要網絡連接和其他內容,因此要單獨構造該類非常復雜。 我該如何模擬此類並提供僅具有get_name方法的內容。 這樣我就可以創建A類並測試該方法。

通過使用mock庫,您可以修補B類,並用MagicMock()對象替換它。 mock庫的設計正是為了執行此類工作,並打破有問題的對象或實際資源的硬依賴性。

在您的簡單示例中,完整的測試將是:

module_a.py

class B():
    def __init__(self):
        print("The awful B class!!!")

    def get_name(self):
        print("The awful B.get_name() method!!!")


class A():
    def __init__(self):
        self.b = B()

    def is_authorized(self):
        name = self.b.get_name()
        if name == 'admin':
            return True
        else:
            return False

module_a_test.py

import unittest
from unittest.mock import patch
from module_a import A


class MyTestCase(unittest.TestCase):

    # patch B class in a_module by a MagicMock instance
    # mock_b_constructor passed to test method
    @patch("module_a.B")
    def test_a(self, mock_b_constructor):
        # B() return value will be the B() instance assigned to a.b property
        mock_b = mock_b_constructor.return_value
        # Now start test:
        a = A()
        # Ok! b is our mock...
        self.assertIs(a.b, mock_b)
        # Not authorized
        self.assertFalse(a.is_authorized())
        mock_b.get_name.return_value = 'admin'
        # Yeah!!! we are admin
        self.assertTrue(a.is_authorized())
        # Sanity check
        mock_b.get_name.return_value = 'guest'
        self.assertFalse(a.is_authorized())

修補程序僅適用於您的測試方法上下文。 這是一個簡單而直接的示例,說明了如何使用mockmock補丁,但是實際情況可能稍微復雜一些。

為B創建一個模擬類,例如:

class MockB(object):
    def get_name(self):
        return 'admin'

然后,在您的測試用例中,將A封裝在使用MockB而不是常規B初始化的類中:

class TestA(A):
    def __init__(self):
        self.b = MockB()

不過,老實說,我不確定這能證明什么。

暫無
暫無

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

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