Python 模拟数据库 connection/unknown 输入单元测试
Python Mocking db connection/unknown type in unit test
新人来到python这里。
我的 class 使用数据库连接来包装一些函数。我已经成功地找出了一些基本的例子。对于我正在使用的更复杂的库,我找不到模拟数据库连接的接近示例。在我的
class DBSAccess():
def __init__(self, db_con):
self.db_con = db_con
def get_db_perm(self, target_user):
## this is where I start having trouble
with self.db_con.cursor() as cursor:
cursor.execute("SELECT CAST(sum(maxperm) AS bigint) \
FROM dbc.diskspace \
WHERE databasename = '%s' \
GROUP BY databasename" % (target_user))
res = cursor.fetchone()
if res is not None:
return res[0]
else:
msg = target_user + " does not exist"
return msg
其中 db_con 是一个 teradata.UdaExec returns 一个连接
udaExec = teradata.UdaExec (appName="whatever", version="1.0", logConsole=True)
db_con = udaExec.connect(method="odbc", system='my_sys', username='my_name', password='my_pswd')
dbc_instance = tdtestpy.DBSaccess (db_con)
因此,为了让我的测试不使用任何实际连接,我必须模拟一些东西。我试过这个组合:
class DBAccessTest(unittest.TestCase):
def test_get_db_free_perm_expects_500(self):
uda_exec = mock.Mock(spec=teradata.UdaExec)
db_con = MagicMock(return_value=None)
db_con.cursor.fetchone.return_value = [500]
uda_exec.connect.return_value = db_con
self.dbc_instance = DBSAccess(db_con)
self.assertEqual(self.dbc_instance.get_db_free_perm("dbc"), 500)
但我的结果一团糟,因为 fetchone 返回的是一个模拟,而不是我期望的 [500] 个项目列表:
AssertionError: <MagicMock name='mock.connect().cursor().[54 chars]312'> != 500
我发现了一些示例,其中有一个 'with block' 用于测试 OS 操作,但没有数据库。另外,我不知道 db_con.cursor 是什么数据类型,所以我无法准确说明 - 我认为游标是在 UdaExecConnection.cursor() 中找到的 Teradata/PyTd.
我需要知道如何模拟响应以允许我在我的方法中测试逻辑。
问题的根源在以下行中:
with self.db_con.cursor() as cursor:
with
行调用 __enter__
method,在您的情况下会生成一个新模拟。
解决方法是mock __enter__
method:
db_con.cursor.return_value.__enter__.return_value = cursor
您的测试:
class DBAccessTest(unittest.TestCase):
def test_get_db_free_perm_expects_500(self):
db_con = MagicMock(UdaExecConnection)
cursor = MagicMock(UdaExecCursor)
cursor.fetchone.return_value = [500]
db_con.cursor.return_value.__enter__.return_value = cursor
self.dbc_instance = DBSAccess(db_con)
self.assertEqual(self.dbc_instance.get_db_perm("dbc"), 500)
def test_get_db_free_perm_expects_None(self):
db_con = MagicMock(UdaExecConnection)
cursor = MagicMock(UdaExecCursor)
cursor.fetchone.return_value = None
db_con.cursor.return_value.__enter__.return_value = cursor
self.dbc_instance = DBSAccess(db_con)
self.assertEqual(self.dbc_instance.get_db_perm("dbc"), "dbc does not exist")
新人来到python这里。 我的 class 使用数据库连接来包装一些函数。我已经成功地找出了一些基本的例子。对于我正在使用的更复杂的库,我找不到模拟数据库连接的接近示例。在我的
class DBSAccess():
def __init__(self, db_con):
self.db_con = db_con
def get_db_perm(self, target_user):
## this is where I start having trouble
with self.db_con.cursor() as cursor:
cursor.execute("SELECT CAST(sum(maxperm) AS bigint) \
FROM dbc.diskspace \
WHERE databasename = '%s' \
GROUP BY databasename" % (target_user))
res = cursor.fetchone()
if res is not None:
return res[0]
else:
msg = target_user + " does not exist"
return msg
其中 db_con 是一个 teradata.UdaExec returns 一个连接
udaExec = teradata.UdaExec (appName="whatever", version="1.0", logConsole=True)
db_con = udaExec.connect(method="odbc", system='my_sys', username='my_name', password='my_pswd')
dbc_instance = tdtestpy.DBSaccess (db_con)
因此,为了让我的测试不使用任何实际连接,我必须模拟一些东西。我试过这个组合:
class DBAccessTest(unittest.TestCase):
def test_get_db_free_perm_expects_500(self):
uda_exec = mock.Mock(spec=teradata.UdaExec)
db_con = MagicMock(return_value=None)
db_con.cursor.fetchone.return_value = [500]
uda_exec.connect.return_value = db_con
self.dbc_instance = DBSAccess(db_con)
self.assertEqual(self.dbc_instance.get_db_free_perm("dbc"), 500)
但我的结果一团糟,因为 fetchone 返回的是一个模拟,而不是我期望的 [500] 个项目列表:
AssertionError: <MagicMock name='mock.connect().cursor().[54 chars]312'> != 500
我发现了一些示例,其中有一个 'with block' 用于测试 OS 操作,但没有数据库。另外,我不知道 db_con.cursor 是什么数据类型,所以我无法准确说明 - 我认为游标是在 UdaExecConnection.cursor() 中找到的 Teradata/PyTd.
我需要知道如何模拟响应以允许我在我的方法中测试逻辑。
问题的根源在以下行中:
with self.db_con.cursor() as cursor:
with
行调用 __enter__
method,在您的情况下会生成一个新模拟。
解决方法是mock __enter__
method:
db_con.cursor.return_value.__enter__.return_value = cursor
您的测试:
class DBAccessTest(unittest.TestCase):
def test_get_db_free_perm_expects_500(self):
db_con = MagicMock(UdaExecConnection)
cursor = MagicMock(UdaExecCursor)
cursor.fetchone.return_value = [500]
db_con.cursor.return_value.__enter__.return_value = cursor
self.dbc_instance = DBSAccess(db_con)
self.assertEqual(self.dbc_instance.get_db_perm("dbc"), 500)
def test_get_db_free_perm_expects_None(self):
db_con = MagicMock(UdaExecConnection)
cursor = MagicMock(UdaExecCursor)
cursor.fetchone.return_value = None
db_con.cursor.return_value.__enter__.return_value = cursor
self.dbc_instance = DBSAccess(db_con)
self.assertEqual(self.dbc_instance.get_db_perm("dbc"), "dbc does not exist")