python - 在 python 单元测试中模拟嵌套函数
问题描述
我试图使用模拟和补丁对 Some.py 中的 some_fun() 进行单元测试,但它没有按预期工作我无法正确修补 db_helper.fetchallmetrics 函数中的 cursor.fetchall() 。下面的函数 test_some() 抛出这样的错误
"AssertionError: ((35235, 4), (342, 3)) != <Mock id='1926131587392'>"
db_helper.py
import settings
import pyodbc
class Connection:
def __init__(self):
self.SERVER= settings.SERVER
self.DATABASE = settings.DATABASE
self.USER = settings.USER
self.PASSWORD = settings.PASSWORD
def connect_db(self):
try:
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+self.SERVER+';DATABASE='+self.DATABASE+';UID='+self.USER+';PWD='+self.PASSWORD)
self.LOGGER.info("Connected to PSP Database")
return conn
except Exception as e:
self.LOGGER.error("Unable to connect Database. {0}".format(e))
def fetchallmetrics(self,connection, query):
cursor = connection.cursor()
cursor.execute(query)
metrics=cursor.fetchall()
return metrics
一些.py
import settings
import db_helper as dh
import constant
class SomeMetrics:
def __init__(self):
# Set the date of which metric is collected
self.metric_collected_date = settings.METRICS_COLLECTED_DATE
self.LOGGER = settings.LOGGER
def some_fun(self, connection):
try:
count = dh.Connection().fetchallmetrics(connection,"SELECT * FROM TABLE")
return count
except Exception as e:
self.LOGGER.error("{0} at some_fun()".format(e))
test_some.py
import unittest
from unittest import mock
from mock import patch, Mock
from Some import SomeMetrics
class TestSomeMetrics(unittest.TestCase):
def setUp(self):
self.km = SomeMetrics()
@mock.patch("db_helper.Connection.connect_db", autospec=True)
@mock.patch("db_helper.Connection.fetchallmetrics", autospec=True)
def test_some_fun(self, mock_some_connection, mock_fetchallmetrics):
posting_count = ((35235, 4), (342, 3))
mock_data_interface = Mock()
mock_fetchallmetrics_interface = Mock()
mock_fetchallmetrics.return_value = mock_fetchallmetrics_interface
mock_fetchallmetrics_interface.cursor.return_value.fetchall.return_value = posting_count
mock_some_connection.return_value = mock_data_interface
self.assertEqual(posting_count,self.km.some_fun(mock_some_connection))
解决方案
在我看来,如果您创建一个单独的类,它会更具可读性MockConnection
:
class MockConnection:
def __init__(self,metrics):
self.metrics = metrics
def fetchallmetrics(self,connection, query):
return self.metrics
# ...
def test_some_fun(self):
posting_count = ((35235, 4), (342, 3))
mock_connection = MockConnection(posting_count)
self.assertEqual(posting_count, self.km.some_fun(mock_connection))
推荐阅读
- python - 将表转换为聚合表
- nativescript - nativescript sidedrawer 不起作用
- c++ - 使用 Visual Studio 在控制台中输出 utf8(宽流)
- xml - 从 Oracle 层次表创建 XML
- html - b-form-input 不接受正常 HTML 输入中的最小数字
- ios - Swift 4 AVcapturesession 不调用 captureOutput 委托
- jenkins - maven PMD插件生成xml格式错误的xml
- python - 错误:Python Range 对象不可调用
- python - 将图像写入文件夹
- linux - 我们如何识别文件中与特定关键字或终端中的字符串匹配的行号?