简体   繁体   English

(Python) Mocking 在另一个方法内部调用的方法的返回值

[英](Python) Mocking the return value of a method called inside another method

I have a class and a function:我有一个 class 和一个 function:

class myclass(object):
    def get_info(self, big_string):
        string_that_always_exists = (big_string.split("Name: myname ")[1]).split("\n")[0]
        if "Name: " in big_string:
            result = self.find_details(string_that_always_exists)
            return result
        else:
            return None

    def find_details(string_that_always_exists):
        # sorts through huge string
        return dictionary_big

What I need to do is write a unit test that will patch the method find_details(string_that_always_exists) so it always equals the same dictionary.我需要做的是编写一个单元测试来修补方法 find_details(string_that_always_exists) 所以它总是等于同一个字典。

I didn't even want to post what I've tried because I really don't understand how the unittest.test framework really works but I think it'll give some ideas:我什至不想发布我尝试过的内容,因为我真的不明白 unittest.test 框架是如何工作的,但我认为它会给出一些想法:

@patch('myclass.find_details')
def test_get_info(self, mock_method):
    mock_method.return_value = Mock(myclass)
    mock_method.find_details.return_value = ["item 1", "item 2", "item 3", "item 4"]
    results = mock_method.get_info("big string with only one guaranteed sub string. Name: ")
    self.assertEqual(results[0], "item 1")

the above doesn't work.以上不起作用。 results always equals a MagicMock object, and not the return values are nowhere in results when I debug the program.结果始终等于 MagicMock object,当我调试程序时,结果中没有返回值。 I think its because I'm not specifying my patch correctly but honestly I don't know.我认为这是因为我没有正确指定我的补丁,但老实说我不知道。

There are some problems with your test.你的测试有一些问题。 First, I'm not sure if you are mocking the correct object, probaly you just don't show the real mock string.首先,我不确定您是否是 mocking 正确的 object,可能您只是没有显示真正的模拟字符串。 The mock string shall reference the object so that it can be imported, including the module name.模拟字符串应引用 object 以便可以导入,包括模块名称。

Second, you are not testing your class, but a mock.其次,你不是在测试你的 class,而是一个模拟。 You should instantiate your real class and test that instead.您应该实例化您的真实 class 并对其进行测试。

And third, you are setting the return_value in the wrong place.第三,您将 return_value 设置在错误的位置。 You already mock the function, so you just have to mock the return value of that function.您已经模拟了 function,因此您只需模拟 function 的返回值。

Last, your test would just return None , as your parameter does not contain "text", but probably this was not your real test.最后,您的测试只会返回None ,因为您的参数不包含“文本”,但这可能不是您真正的测试。 As a side note: it helps to provide real working code, even if it does not do what you want.作为旁注:它有助于提供真正的工作代码,即使它没有做你想要的。

Your test could look something like this (assuming you class lives in mymodule.py ):您的测试可能看起来像这样(假设您 class 位于mymodule.py中):

import unittest
from unittest.mock import patch

from mymodule import myclass

class TestMyClass(unittest.TestCase):
    @patch('mymodule.myclass.find_details')
    def test_get_info(self, mock_method):
        mock_method.return_value = ["item 1", "item 2", "item 3", "item 4"]
        cls = myclass()
        results = cls.get_info("Big string with text. Name: ")
        self.assertEqual(results[0], "item 1")

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

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