简体   繁体   English

Python:使用@patch 在方法中模拟类的实例

[英]Python: Mocking an instance of a class inside a method using @patch

I have a method foo in Python that creates a Service class.我在 Python 中有一个方法foo可以创建一个服务类。 I want to mock the Service class but when I run the test, it still attempts to instantiate the class.我想模拟 Service 类,但是当我运行测试时,它仍然尝试实例化该类。 Here is the simplified version of my setup:这是我的设置的简化版本:

class Service:
    def __init__(self, service):
        self.service_stuff = service

    def run_service(self):
        do_service_stuff()

def foo:
    new_service = Service("bar")
    new_service.run_service()

Then my unit test:然后我的单元测试:

@patch('mymodule.service_file.Service')
def test_foo(self, mock_service):
    foo()

I would like to run foo, but have it use my mocked object instead of creating an actual Service instance, but instead, when I run it, it tries to instantiate an actual instance of Service() and runs foo() as usual even though it seems to recognize the string signature I've put into patch.我想运行 foo,但让它使用我的模拟对象而不是创建实际的 Service 实例,但是当我运行它时,它会尝试实例化 Service() 的实际实例并像往常一样运行 foo()它似乎可以识别我放入补丁中的字符串签名。 Why is this happening?为什么会这样?

Figured it out: The patch reference to the class had to be of its imported name in the method itself rather than the original class, similar to https://stackoverflow.com/a/32461515/4234853弄清楚了:对类的补丁引用必须是方法本身中的导入名称,而不是原始类,类似于https://stackoverflow.com/a/32461515/4234853

So the patch should look like: @patch('mymodule.foo_file.Service') instead of trying to patch the class directly.所以补丁应该看起来像: @patch('mymodule.foo_file.Service')而不是试图直接修补类。

In this case, it might be easier to make your function more test-friendly:在这种情况下,使您的函数更易于测试可能会更容易:

def foo(cls=Service):
    new_service = cls("bar")
    new_service.run_service()

Then your test doesn't need to patch anything.那么你的测试不需要修补任何东西。

def test_foo(self):
    mock_service = Mock()
    foo(mock_service)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM