如何将模拟 @patch 装饰器与本地导入的库一起使用?

How do I use mock @patch decorator with a locally imported library?

我的目录结构如下所示:

myproject/
├── mymodule/
│   ├── foo.py
│   └── model/
│        └── functions.py
│
└── tests/
    └── footest.py

我的 foo.py 文件有一个本地导入,如下所示:

from .model.functions import MyClass

我试图在我的一个测试中模拟 MyClass 方法之一,但我不知道如何使用 @patch 装饰器来完成它。通常我这样做:

class CheckLambdaHandler(unittest.TestCase):
    @patch('requests.post')
    def test_post_error(self, mocked_post):
        # Test which uses requests.post

但是当我尝试对本地导入做类似的事情时,它中断了:

class CheckLambdaHandler(unittest.TestCase):
    @patch('.model.functions.MyClass.function')
    def test_post_error(self, mocked_post):
        # Test which uses requests.post

因为我猜@patch 在“.”上拆分了一个字符串。这意味着您不能使用本地进口产品?

ValueError: Empty module name

还有谁知道在这里做什么?我需要更改导入吗?在测试中?在实际代码中?

来自docs

target should be a string in the form 'package.module.ClassName'. The target is imported and the specified object replaced with the new object, so the target must be importable from the environment you are calling patch() from.

由于测试代码通常不驻留在包中,因此相对导入在这里没有意义。

更改补丁(测试代码)中的目标 "path" 以使用绝对路径。您的库代码无需更改。假设 mymodule 是顶级包名,myproject 是项目根目录,它看起来像:

@patch('mymodule.model.functions.MyClass.function')