在sqlalchemy上使用python模拟库
我正在使用sqlalchemy查询数据库中的项目。同时,我对单元测试还不熟悉,我正在尝试学习如何进行单元测试来测试我的数据库。我尝试使用模拟库进行测试,但到目前为止,它似乎非常困难 所以我制作了一段代码,它创建了一个在sqlalchemy上使用python模拟库,python,unit-testing,sqlalchemy,mocking,python-mock,Python,Unit Testing,Sqlalchemy,Mocking,Python Mock,我正在使用sqlalchemy查询数据库中的项目。同时,我对单元测试还不熟悉,我正在尝试学习如何进行单元测试来测试我的数据库。我尝试使用模拟库进行测试,但到目前为止,它似乎非常困难 所以我制作了一段代码,它创建了一个会话对象。此对象用于连接到数据库 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarati
会话
对象。此对象用于连接到数据库
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.exc import OperationalError, ArgumentError
test_db_string = 'postgresql+psycopg2://testdb:hello@localhost/' \
'test_databasetable'
def get_session(database_connection_string):
try:
Base = declarative_base()
engine = create_engine(database_connection_string)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
connection = session.connection()
return session
except OperationalError:
return None
except ArgumentError:
return None
所以我为这个函数做了一个单元测试用例:
import mock
import unittest
from mock import sentinel
import get_session
class TestUtilMock(unittest.TestCase):
@mock.patch('app.Utilities.util.create_engine') # mention the whole path
@mock.patch('app.Utilities.util.sessionmaker')
@mock.patch('app.Utilities.util.declarative_base')
def test_get_session1(self, mock_delarative_base, mock_sessionmaker,
mock_create_engine):
mock_create_engine.return_value = sentinel.engine
get_session('any_path')
mock_delarative_base.called
mock_create_engine.assert_called_once_with('any_path')
mock_sessionmaker.assert_called_once_with(bind=sentinel.engine)
正如您在我的单元测试中所看到的,我无法在get_session()
中从第session=DBSession()行开始测试代码。到目前为止,在谷歌搜索之后,我还无法确定返回的mock值是否也可以用于模拟函数调用——比如,我模拟了session
对象,并验证我是否调用了session.connection()
上述编写单元测试用例的方法正确吗?有更好的方法吗?首先,您还可以通过
self.assertEqual(get_session('any_path'), mock_sessionmaker.return_value.return_value)
此外,mock\u delarative\u base.called
不是断言,不能失败。换成
self.assertTrue(mock_delarative_base.called)
一般考虑
编写这样的测试可能非常耗时,并使生产代码与测试代码真正耦合。最好编写您自己的包装器,为您的业务代码提供一个舒适的接口,并使用一些模拟和真实(简单)测试对其进行测试:您应该信任sqlalchemy
实现,只需测试包装器如何调用它
之后,您可以通过一个可以控制或使用mock的假对象来模拟包装器,并检查代码如何调用它,但包装器将只显示一些业务接口,模拟应该非常简单。感谢您的输入。我只是想知道如何模拟上面示例中的自定义对象。由于某些函数依赖于其他函数,我想使用mocking来断言这些函数是用正确的参数调用的。非常感谢你的帮助。