Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在sqlalchemy上使用python模拟库_Python_Unit Testing_Sqlalchemy_Mocking_Python Mock - Fatal编程技术网

在sqlalchemy上使用python模拟库

在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

我正在使用sqlalchemy查询数据库中的项目。同时,我对单元测试还不熟悉,我正在尝试学习如何进行单元测试来测试我的数据库。我尝试使用模拟库进行测试,但到目前为止,它似乎非常困难

所以我制作了一段代码,它创建了一个
会话
对象。此对象用于连接到数据库

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来断言这些函数是用正确的参数调用的。非常感谢你的帮助。