如何在 Python 中模拟 cx_Oracle 光标
How to mock cx_Oracle cursor in Python
我在 class 中有以下两个函数,我需要模拟数据库连接和游标结果。 cx_Oracle.connect 成功修补它按预期工作。但是游标、callfunc、fetch_all 不会被模拟。知道什么是正确的语法吗?
class dbconnect:
def db_connect(self, connection_details):
connection = cx_Oracle.connect(user_name,pwd,<connection_string>)
return connection
def execute_function(self, sqlFunction, args):
cursor = self.connection.cursor()
res=cursor.callfunc(sqlFunction, cursor.var(cx_Oracle.CURSOR), args)
results = {'headers' : [x[0] for x in res.description],
'data': res.fetchall()
}
cursor.close()
return results
我的模拟代码
with mock.patch('dbconnect.cx_Oracle.connect') as mockOracle:
result_set = {}
mockOracle.cursor.callfunc.fetch_all = result_set
实际上您根本不需要 "mock" 建立连接和光标!您可以自己简单地子类化连接和游标,如下所示:
class MyConnection(cx_Oracle.Connection):
def cursor(self, scrollable=False):
return MyCursor(self, scrollable)
class MyCursor(cx_Oracle.Cursor):
def execute(self, sql, args):
result = super(MyConnection, self).execute(sql, args)
print("My mock execute...")
return result
我不确定这是否是您的意图,或者您是否知道这种可能性。有了它,您可以添加新功能,也可以覆盖或扩展现有功能。
我有一个类似的问题,所以我用我创建的 class 修补了 cx_Oracle.connect()
方法,所以它既可以在上下文管理器中工作,也可以在 returns 模拟游标中工作。游标应该适用于 fetchmany
和 fetchall
import cx_Oracle
class MockCursor:
def __init__(self, *args, **kwargs):
self.fetched = False
self.rows = None
self.description = [("id",), ("name",)]
def callfunc(self, *args):
return self
@staticmethod
def var(*args):
pass
@staticmethod
def execute(query):
pass
@staticmethod
def close():
pass
def fetchmany(self, *args):
if not self.fetched:
self.rows = self.fetch_rows()
self.fetched = True
return next(self.rows)
@staticmethod
def fetchall():
return [
(1, "TEST A"),
(2, "TEST B"),
(3, "TEST C"),
]
def fetch_rows(self):
yield self.fetchall()
yield None
class MockConnect:
def __enter__(self, *args, **kwargs):
return self
def __exit__(self, type, value, traceback):
pass
@staticmethod
def cursor():
return MockCursor()
@staticmethod
def close():
pass
@mock.patch.object(cx_Oracle, "connect")
def test_foo(mock_connect):
mock_connect.return_value = MockConnect()
我在 class 中有以下两个函数,我需要模拟数据库连接和游标结果。 cx_Oracle.connect 成功修补它按预期工作。但是游标、callfunc、fetch_all 不会被模拟。知道什么是正确的语法吗?
class dbconnect:
def db_connect(self, connection_details):
connection = cx_Oracle.connect(user_name,pwd,<connection_string>)
return connection
def execute_function(self, sqlFunction, args):
cursor = self.connection.cursor()
res=cursor.callfunc(sqlFunction, cursor.var(cx_Oracle.CURSOR), args)
results = {'headers' : [x[0] for x in res.description],
'data': res.fetchall()
}
cursor.close()
return results
我的模拟代码
with mock.patch('dbconnect.cx_Oracle.connect') as mockOracle:
result_set = {}
mockOracle.cursor.callfunc.fetch_all = result_set
实际上您根本不需要 "mock" 建立连接和光标!您可以自己简单地子类化连接和游标,如下所示:
class MyConnection(cx_Oracle.Connection):
def cursor(self, scrollable=False):
return MyCursor(self, scrollable)
class MyCursor(cx_Oracle.Cursor):
def execute(self, sql, args):
result = super(MyConnection, self).execute(sql, args)
print("My mock execute...")
return result
我不确定这是否是您的意图,或者您是否知道这种可能性。有了它,您可以添加新功能,也可以覆盖或扩展现有功能。
我有一个类似的问题,所以我用我创建的 class 修补了 cx_Oracle.connect()
方法,所以它既可以在上下文管理器中工作,也可以在 returns 模拟游标中工作。游标应该适用于 fetchmany
和 fetchall
import cx_Oracle
class MockCursor:
def __init__(self, *args, **kwargs):
self.fetched = False
self.rows = None
self.description = [("id",), ("name",)]
def callfunc(self, *args):
return self
@staticmethod
def var(*args):
pass
@staticmethod
def execute(query):
pass
@staticmethod
def close():
pass
def fetchmany(self, *args):
if not self.fetched:
self.rows = self.fetch_rows()
self.fetched = True
return next(self.rows)
@staticmethod
def fetchall():
return [
(1, "TEST A"),
(2, "TEST B"),
(3, "TEST C"),
]
def fetch_rows(self):
yield self.fetchall()
yield None
class MockConnect:
def __enter__(self, *args, **kwargs):
return self
def __exit__(self, type, value, traceback):
pass
@staticmethod
def cursor():
return MockCursor()
@staticmethod
def close():
pass
@mock.patch.object(cx_Oracle, "connect")
def test_foo(mock_connect):
mock_connect.return_value = MockConnect()