python - 如何对自定义上下文管理器进行单元测试?
问题描述
我有以下函数,它产生一个与语句pyodbc.connect()
一起使用的对象:with
from contextlib import contextmanager
import pyodbc
@contextmanager
def get_db_connection(conn_string, **kwargs):
try:
conn = pyodbc.connect(conn_string, **kwargs)
yield conn
except Exception as connection_error:
raise ValueError('Could not connect to db.', connection_error) from None
finally:
conn.close()
我想为此函数编写单元测试,以测试连接是否可以打开、关闭,并且在发生错误时ValueError
引发 a。我有:
from unittest.mock import Mock, patch
from db.query import get_db_connection
@patch('db.query.pyodbc.connect')
def test_get_db_connection(self, mock_connect):
conn_string = Mock()
with get_db_connection(conn_string) as conn:
pass
# print(conn) is acceptable here and prints:
# <MagicMock name='connect()' id='2595126451264'>
mock_connect.assert_called_once()
mock_connect.side_effect = Exception()
def _t():
with get_db_connection(conn_string) as conn:
pass
self.assertRaises(UnboundLocalError, _t)
这里的一切都运行并通过,但我注意到在语句范围应该关闭conn
后可用。with
如何编写用于get_db_connection()
使用的单元测试,以mock
使conn
变量的行为符合我的预期?还是有另一种方法可以对其进行充分的单元测试?
解决方案
利用
conn.close.assert_not_called()
检查连接是否在第一个with
块中打开。conn.close.assert_called_once()
检查连接是否在第一个with
块之后关闭。- 当块中发生错误时,已经检查了是否没有建立连接
try
- UnboundLocalError: local variable 'conn' referenced before assignment
推荐阅读
- android - Android 在 android Service 中使用 LocalBroadcastManager
- sql - SQL日期查询带括号的区别
- php - 连接 MySQL 数据表中的 2 行的 PHP 下拉菜单
- sprite-kit - 为什么将 SKNode() 分配给变量时会产生无穷无尽的敌人?
- javascript - 为什么 document.body.requestFullscreen() 仅在第一次调用时起作用?
- wireshark - 是否有用于 NATS 协议的wireshark 解剖器(https://nats.io/)
- ibm-cloud - 我收到了不止一份 Speech to text IBM 云服务的最终成绩单
- java - 如何不使用随机库等构建随机数?
- javascript - 在 create-react-app 中导入 png 文件不显示图像
- javascript - 未捕获的类型错误:mychart.update 不是函数