【问题标题】:Mock a class with tedious __init__用乏味的 __init__ 模拟一个类
【发布时间】:2014-12-10 01:22:37
【问题描述】:

我有一个实际连接到服务并执行身份验证和其他操作的类,但是所有这些都在我的代码中的其他地方进行了很好的测试,我只想在以下测试中进行模拟:

带有繁琐的 __init__ 的对象

class B(object):
    def __init__(self, username, password):
        con = connect_to_service() # 
        auth = con.authenticate(username, password)

    def upload(self)
        return "Uploaded"

class A(object):
    def send():
       b = B('user', 'pass')
       b.upload()

tests.py

# Now, I want here to test A, and since it uses B, I need to mock it, but I can't get it to work.
def test_A():
    # Here I need to mock B and B.upload, I tried this:
    a = A()
    b = Mock()
    b.upload.return_value='Hi'
    a.send()

但是这个测试失败了,因为它到达了 B.init 上的 auth(),我想成为一个 Mock 模型。

【问题讨论】:

    标签: python django mocking pytest


    【解决方案1】:

    我认为这是mock.patch 的典型用例。注意patch装饰器需要主模块变为__main__的模块的完整路径

    from mock import patch, Mock
    from abmodule import A,  B #Where A and B are
    
    @patch("abmodule.B")
    def test_A(bmock):
        # Set B costructor to return a Mock object
        bmock.return_value = Mock()
        bmock.upload.return_value='Hi'
        a = A()
        a.send()
        #Check if upload was called!
        bmock.return_value.upload.assert_called_with()
    

    之后,您可以在代码的另一部分再次使用原始 B:修补后的版本仅在函数范围内。

    【讨论】:

      【解决方案2】:

      您需要使用模拟的 B 修补实际类。py.test 为此提供了monkeypatch 夹具:

      import unittest.mock
      import mut  # module under test, where A and B are defined.
      
      def test_A(monkeypatch):
          b = unitest.mock.Mock()
          b.upload.return_value = 'Hi'
          monkeypatch.setattr(mut, 'B', b)
          a = mut.A()
          a.send()
      

      【讨论】:

        猜你喜欢
        • 2020-09-23
        • 2015-11-27
        • 1970-01-01
        • 2017-10-23
        • 1970-01-01
        • 2019-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多