Python模拟工厂子类和方法

2024-04-25 00:28:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要模拟MyClassFactory,它返回一个MyClass对象。这个对象有一个方法getNum,我也需要模拟。我不知道该怎么做,因为工厂不再返回MyClass,而是返回<MagicMock name='mock().create()'...>。你知道吗

import unittest
from mock import MagicMock, Mock, patch

class MyClass:
    def getNum(self):
        return 10

class MyClassFactory:
    def create(self):
        return MyClass()

class Runner:
    def foo(self):
        myClassFactory = MyClassFactory()
        myClass = myClassFactory.create()

        num = myClass.getNum()

        if num == 10:
            print("foo successful")
        else:
            print("foo fail, num={}".format(num))

class TestRoute(unittest.TestCase):
    # Attempt at patching the methods
    @patch("__main__.MyClassFactory", create=True, new=MagicMock())
    @patch("__main__.MyClass", create=True, new=MagicMock())
    @patch("__main__.MyClass.getNum", create=True, new=MagicMock(return_value=11))
    def test_foo_fail(self):
        runner = Runner()
        runner.foo()

if __name__ == '__main__':
    unittest.main()

实际输出:

foo fail, num=<MagicMock name='mock().create().getNum()' id='140554774258128'>

期望输出:

foo fail, num=11

这不是我想要的。我试图对mock方法使用return_value=11,但没有调用它。你知道吗

TLDR:我有一个工厂,我需要模仿。它返回一个类。该类有一个方法,我还需要模拟返回值,但我不能这样做。基本上我想把mock().create().getNum()变成11。你知道吗


Tags: selfreturnfoomaindefcreatemyclassmock
1条回答
网友
1楼 · 发布于 2024-04-25 00:28:00

这是你的第一个补丁

@patch("__main__.MyClass", create=True, new=MagicMock())

用MagicMock()替换“main.MyClass”的类实例化。下一个补丁:

@patch("__main__.MyClass.getNum", create=True, new=MagicMock(return_value=11))

最后尝试调用MagicMock()对象的方法,而不是原始的main.MyClass,这将导致您看到的输出。你知道吗

You need to attach mocks as attributes and set up each child mock.与其在测试前修补,不如在调用foo之前尝试修补。你知道吗

import unittest
from mock import MagicMock, Mock, patch

class MyClass:
    def getNum(self):
        return 10

class MyClassFactory:
    def create(self):
        return MyClass()

class Runner:
    def foo(self):
        myClassFactory = MyClassFactory()
        myClass = myClassFactory.create()
        print(myClassFactory)
        print(myClass)
        num = myClass.getNum()
        if num == 10:
            print("foo successful")
        else:
            print("foo fail, num={}".format(num))

class TestRoute(unittest.TestCase):
    def test_foo_fail(self):
        getNumMock = MagicMock(return_value = 20)

        myClassMock = MagicMock()
        myClassMock.getNum = getNumMock

        createMock = MagicMock(return_value = myClassMock)

        myClassFactoryMock = MagicMock()

        createMock.attach_mock(getNumMock, "getNum")
        myClassFactoryMock.attach_mock(createMock, "create")

        with patch('__main__.MyClassFactory', create=True, return_value=myClassFactoryMock):
            runner = Runner()
            runner.foo()
if __name__ == '__main__':
    unittest.main()

相关问题 更多 >