繁体   English   中英

奇怪的修补行为

[英]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.

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