如何模拟 python 中的后续函数调用?

How to mock subsequent function calls in python?

我是 python 中测试和测试的新手。我有一个看起来像这样的 python class :

文件名:my_hive.py

from pyhive import hive

class Hive:
    def __init__(self, hive_ip):
        self.cursor = hive.connect(hive_ip).cursor()

    def execute(self, command):
        self.cursor.execute(command)

我想模拟这些函数:pyhive.hive.connectpyhive.Connection.cursor(被我的 class 用作 hive.connect(hive_ip).cursor())和 pyhive.Cursor.execute(被我的 class as self.cursor.execute(command) in execute 方法).

我能够模拟函数调用 hive.connect,而且我已经能够断言它已被我给出的 hive_ip 调用,如下所示。

import unittest
import mock

from my_hive import Hive

class TestHive(unittest.TestCase):
    @mock.patch('pyhive.hive.connect')
    def test_workflow(self, mock_connect):
        hive_ip = "localhost"
        processor = Hive(hive_ip)

        mock_connect.assert_called_with(hive_ip)

但是我如何确保像 .cursor()self.cursor.execute() 这样的后续函数调用也被调用了? hive.connect(hive_ip) returns pyhive.hive.Connection 的一个实例,它有一个名为 cursor

的方法

我试过像这样添加模拟:

import unittest
import mock

from hive_schema_processor import HiveSchemaProcessor

class TestHive(unittest.TestCase):
    @mock.patch('pyhive.hive.connect')
    @mock.patch('pyhive.hive.Connection.cursor')
    def test_workflow(self, mock_connect, mock_cursor):
        hive_ip = "localhost"
        processor = Hive(hive_ip)

        mock_connect.assert_called_with(hive_ip)
        mock_cursor.assert_called()

但是测试失败并抱怨:

AssertionError: expected call not found.
Expected: cursor('localhost')
Actual: not called.

您的问题是您已经模拟了 connect,因此对 connect 结果的后续调用将在模拟对象上进行,而不是在真实对象上进行。 要检查该调用,您必须改为检查返回的模拟对象:

class TestHive(unittest.TestCase):
    @mock.patch('pyhive.hive.connect')
    def test_workflow(self, mock_connect):
        hive_ip = "localhost"
        processor = Hive(hive_ip)

        mock_connect.assert_called_with(hive_ip)
        mock_cursor = mock_connect.return_value.cursor
        mock_cursor.assert_called()

对模拟的每次调用都会产生另一个模拟对象。 mock_connect.return_value 为您提供通过调用 mock_connect 返回的模拟,而 mock_connect.return_value.cursor 包含另一个将实际调用的模拟。