【问题标题】:Mocking Python object instantiation模拟 Python 对象实例化
【发布时间】:2018-10-25 18:17:43
【问题描述】:

我想模拟一个对象的实例化,以便返回的对象是一个 MagicMock 对象。我的文件结构如下:

home_folder
|
|-namespace
|  |-Class1.py
|  |-Class2.py
|
|-tests
   |-unit_tests
      |-test_Class2.py

Class1.py的内容是:

class Class1:
    ... class members ...

Class2.py的内容是:

from Class1 import Class1

class Class2(Class1):

    classMethod(self):
        objInst = Class1()

        ... some logic ...

        return objInst

test_class2.py的内容是:

from unittest import TestCase
from Class1 import Class1
from Class2 import Class2
from unittest.mock import patch, MagicMock

class TestClass2(TestCase):

    @patch("namespace.Class2.Class1")
    def test_classMethod(self, mock_class1):
        cl2Obj = Class2()

        cl1Obj = MagicMock(Class1())

        mock_class1.return_value = cl1Obj

        r = cl2Obj.classMethod()

        self.assertEqual(cl1Obj, r)

运行这个测试给了我:

<Class1.Class1 object at 0xnum> != <MagicMock name='Class1()' spec='Class1' id=num>

我尝试过使用

@patch("namespace.Class1.Class1")

但这并没有帮助。尝试

mock_class1.__init__.return_value = cl1Obj

抛出一个错误提示

Attribute Error: 'method' object has no attribute 'return_value'

如何模拟 objInst = Class1() 以便 objInst 最终持有一个 MagicMock 对象?

【问题讨论】:

    标签: python python-3.x namespaces mocking python-unittest


    【解决方案1】:

    你让这变得比它需要的更复杂。 mock_class1 已经是一个可调用对象,并且将返回另一个模拟对象——无论它被调用到哪里,都是同一个模拟对象。所以这很好用:

    class TestClass2(TestCase):
    
        @patch("namespace.Class2.Class1")
        def test_classMethod(self, mock_class1):
            cl2Obj = Class2()
            cl1Obj = mock_class1()
            r = cl2Obj.classMethod()
            self.assertEqual(cl1Obj, r)
    

    【讨论】:

    • 谢谢,但这不起作用。 cl2Obj.classMethod() 正在返回 Class1 的实例,根本不是模拟对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多