[英]Weird patching behavior
我有一个类(Cat)和一个方法(say_hello)来修补。 当我只修补课程时,一切都运作良好。 当我仅修补方法时,它也有效。 当我同时修补这两个时,该类没有修补,但该方法已正确修补。
main.py
from hello import say_hello
from cat import Cat
cat = Cat('kitty')
def main():
print(say_hello())
hello.py
def say_hello():
return "No mocked"
test.py
import unittest
from unittest.mock import patch
class TestStringMethods(unittest.TestCase):
# cat.Cat is not patched correctly if both patch statements are there
@patch('cat.Cat')
@patch('main.say_hello')
def test_kitty(self, say_hello_mock, cat_mock):
say_hello_mock.return_value = "Mocked"
from main import main
main()
if __name__ == '__main__':
unittest.main()
如果您运行上一个示例,则会创建一个真正的Cat。 如果您对main.say_hello的补丁进行评论,则会创建一个模拟Cat。
我不知道为什么补丁装饰器不工作,但你可以使用这个解决方案:
def test_kitty(self):
with patch('cat.Cat') as cat_mock:
with patch('main.say_hello') as hello_mock:
from main import main
main()
在我的问题上,第一个调用的补丁是main.say_hello。 我将触发主模块的导入,cat将被实例化为真正的Cat实例。 然后猫补了,但为时已晚。
诀窍是颠倒补丁的顺序:
@patch('main.say_hello')
@patch('cat.Cat')
def test_kitty(self, cat_mock, say_hello_mock):
say_hello_mock.return_value = "Mocked"
from main import main
main()
当装饰器以向外的顺序调用时,Cat被修补,然后say_hello被修补,触发主模块的导入(实例化一个模拟的Cat)。
@patch('cat.Cat')
调用将首先导入cat
模块。 此时, cat.cat
对象是从原始Cat
类创建的,它将引用此原始类作为其类型。
现在,您将使用对mock的引用替换对cat.Cat
的原始引用 。 这对对象不再有影响。
您修补了类的属性或方法,实例将间接更改,但替换引用会保持原始类不变。
say_hello()
在hello.py
定义,所以这个:
@patch('main.say_hello')
应改为:
@patch('hello.say_hello')
那么你可以决定在装饰器中先嘲笑哪个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.