如何模拟类方法的cls参数?

时间:2019-07-02 09:02:12

标签: python unit-testing mocking class-method

我有一个使用 classmethod 作为自定义构造函数的类。

# my_module.py
class MyClass:
    def __init__(self, my_arg):
        self.my_arg = my_arg

    @classmethod
    def my_constructor(cls):
        return cls("my val")

我想在测试中断言已使用适当的值调用了构造函数,并返回了实例。

我尝试了几种修补方式,但是无法正常工作。

我尝试使用 wraps 参数修补整个类,以执行真实的方法。

# my_test.py
from unittest import TestCase
from unittest.mock import patch

from my_module import MyClass


class MyClassTestCase(TestCase):
    @patch("my_module.MyClass", wraps=MyClass)
    def test_my_constructor(self, my_class):
        result = my_class.my_constructor()
        my_class.assert_called_once_with("my val")
        self.assertEqual(result, my_class.return_value)

这里的问题是_my_module.MyClass.my_class_方法获取的 cls 参数不是我的 Mock ,而是真正的 MyClass 课。

我的另一个想法是使用 patch.object 修补真正的 __ init __ 构造函数,但这也不起作用。这次是因为 __ init __ 不应该返回任何内容,但是 MagicMock 具有返回值。

# my_test.py
from unittest import TestCase
from unittest.mock import patch

from my_module import MyClass


class MyClassTestCase(TestCase):
    @patch.object(MyClass, "__init__")
    def test_my_constructor(self, init):
        result = MyClass.my_constructor()
        init.assert_called_once_with("my val")
        self.assertEqual(result, init.return_value)

_my_constructor_已使用给定参数实例化并返回了 MyClass 类的实际方法吗?

1 个答案:

答案 0 :(得分:0)

模拟__new__代替__init__ 并且断言将是 init.assert_called_once_with(MyClass, "my val")