Python 单元测试:如何对包含数据库操作的模块进行单元测试?

新手上路,请多包涵

我正在使用 pymysql 客户端库连接到真实数据库。我在模块中有一个函数,我在其中使用 pymysql 连接到数据库并且只执行数据库插入操作。如何在 python 中对这个函数进行单元测试而不触及真实数据库?

 import pymysql

def connectDB(self):

# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='user',
                             password='passwd',
                             db='db')

try:
    with connection.cursor() as cursor:
        # Create a new record
        sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"
        cursor.execute(sql, ('newuser@some.com', 'newpassword'))

    connection.commit()

我的python版本是2.7。

原文由 user2301 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 692
2 个回答

您可以使用 patch ,如下所示:

 from unittest.mock import patch, MagicMock

@patch('mypackage.mymodule.pymysql')
def test(self, mock_sql):
    self.assertIs(mypackage.mymodule.pymysql, mock_sql)

    conn = Mock()
    mock_sql.connect.return_value = conn

    cursor      = MagicMock()
    mock_result = MagicMock()

    cursor.__enter__.return_value = mock_result
    cursor.__exit___              = MagicMock()

    conn.cursor.return_value = cursor

    connectDB()

    mock_sql.connect.assert_called_with(host='localhost',
                                        user='user',
                                        password='passwd',
                                        db='db')

    mock_result.execute.assert_called_with("sql request", ("user", "pass"))

原文由 uwevil 发布,翻译遵循 CC BY-SA 3.0 许可协议

您需要一系列假数据库,称为存根,它们返回硬编码值。在测试期间,使用这些存根代替真实数据库。我不熟悉 Python,但在 C++ 中执行此操作的一种方法是让您的对象接收数据库作为构造函数参数。在生产代码中,您使用真实的数据库参数,在测试存根中。这是可以做到的,因为构造函数需要一个指向公共基类的指针。即使它不是为 Python 编写的,我也建议阅读 Roy Osherove 的第一章:单元测试的艺术。这本书清楚地解释了为什么这些假数据库是存根而不是模拟。

原文由 robert 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题