我想建立一个模拟数据库(与创建测试数据库相反,如果可能的话)来检查数据是否被正确地查询并转换为Pandas数据框架。我有一些关于模拟和单元测试的经验,并且以前成功地设置了先前的测试。然而,我在应用如何模拟像数据库这样的真实对象进行测试方面遇到了困难。
目前,当我的测试运行时,我遇到了生成结果的困难。我认为我没有正确地模拟数据库对象,我错过了其中涉及的某个步骤或者我的思维过程是错误的。我将我的测试和要测试的代码放在同一个脚本中以简化事情。
- 我已经彻底阅读了Python unittest和mock文档,所以我知道它是做什么和如何工作的(在大多数情况下)。
- 我已经阅读了无数关于mocking的帖子,包括Stack内部和外部的帖子。它们有助于理解一般概念以及可以在所述特定情况下完成哪些工作,但我无法在我的情况下使其正常工作。
- 我尝试模拟函数的各个方面,包括数据库连接、查询和使用“pd_read_sql(query,con)”函数,但都没有成功。我认为这是我最接近目标的方式。
我的最新测试代码
import pandas as pd
import pyodbc
import unittest
import pandas.util.testing as tm
from unittest import mock
# Function that I want to test
def p2ctt_data_frame():
conn = pyodbc.connect(
r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=My\Path\To\Actual\Database\Access Database.accdb;'
)
query = 'select * from P2CTT_2016_Plus0HHs'
# I want to make sure this dataframe object is created as intended
df = pd.read_sql(query, conn)
return df
class TestMockDatabase(unittest.TestCase):
@mock.patch('directory1.script1.pyodbc.connect') # Mocking connection
def test_mock_database(self, mock_access_database):
# The dataframe I expect as the output after query is run on the 'mock database'
expected_result = pd.DataFrame({
'POSTAL_CODE':[
'A0A0A1'
],
'DA_ID':[
1001001
],
'GHHDS_DA':[
100
]
})
# This is the line that I believe is wrong. I want to create a return value that mocks an Access table
mock_access_database.connect().return_value = [('POSTAL_CODE', 'DA_ID', 'GHHDS_DA'), ('A0A0A1', 1001001, 100)]
result = p2ctt_data_frame() # Run original function on the mock database
tm.assert_frame_equal(result, expected_result)
if __name__ == "__main__":
unittest.main()
我期望使用模拟数据库对象运行测试后的预期数据框与结果相同,但实际情况并非如此。
目前,当我尝试模拟数据库时,如果打印出结果,我会得到:
空的数据框 列: [] 索引: []
此外,在测试运行后,我会收到以下错误:
断言错误:数据框不同;
数据框形状不匹配
【左侧】:(0, 0)
【右侧】:(1, 3)