簡體   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