首页 > 解决方案 > 如何模拟 cursor.execute

问题描述

我正在尝试在不集成 mysql 数据库的情况下为以下代码编写测试。是否可以?

def sql_query_select(select, table, condition, variable):
    cursor = database_connection("cursor")
    sql_query = "SELECT " + select + " from " + table + " where " + condition + " = " + "'" + variable + "'"
    cursor.execute(sql_query)
    try:
        response = cursor.fetchone()[0]
    except:
        response = cursor.fetchone()
    cursor.close()
    return response

我尝试了以下代码作为测试

@mock.patch("lambda_function.database_connection")
    @mock.patch("pymysql.cursors.Cursor.execute")
    def test_sql_query_select(self, mock_database_connection, mock_execute):
        mock_database_connection.return_value = "cursor"
        mock_execute.return_value = "test"
        self.assertEqual(lambda_function.sql_query_select("select", "table", "condition", "variable"), "execute")

但收到以下错误,不知道如何继续。

E       AttributeError: 'str' object has no attribute 'execute'

标签: pythonpython-unittest

解决方案


您已经在尝试模拟database_connection(). 您也不需要模拟cursor.execute(),因为您可以将您想要的行为注入database_connection(). 问题是您需要在使用对象而不是定义对象的位置模拟对象。它看起来像sql_query_select()在一个名为 的文件中lambda_function.py,所以模拟看起来像这样:

@mock.patch(lambda_function.database_connection)
def test_sql_query_select(self, mock_database_connection):
    mock_record = ('record one', 'record two')
    mock_database_connection.return_value.fetchone.return_value = mock_record
    result = lambda_function.sql_query_select("select", "table", "condition", "variable")
    self.assert_equal(mock_record, result)

这种测试的一个问题是它完全忽略了sql_query_select(). 一种解决方案是验证是否database_connection.return_value.execute已调用。

这也令人不满意,因为您正在测试实现而不是行为。


推荐阅读