如何测试是否调用了SQL Alchemy事务?

问题描述 投票:0回答:1

我如何测试以下代码,其中引擎原本是SQLAlchemy引擎对象?不幸的是,我提供的测试用例无法正常工作。我能够检查引擎的begin方法是否被调用,但不能检查execute语句。执行execute_mock方法后,再也不会调用第二个fetch_data

class A():
    def __init__(self, engine):
        self.engine = engine

    def fetch_data(self):
        with self.engine.begin() as trans:
            trans.execute("SELECT * FROM XXX")

from unittest.mock import MagicMock
def test_A():
    execute_mock = MagicMock()
    engine_mock = MagicMock()
    engine_mock.begin.return_value.execute = execute_mock

    A(engine_mock)
    execute_mock.assert_not_called()
    A.fetch_data()
    execute_mock.assert_called_with("SELECT * FROM XXX")
python unit-testing sqlalchemy mocking python-unittest
1个回答
0
投票

您没有正确嘲笑trans上下文管理器。这是单元测试解决方案:

a.py

class A():
    def __init__(self, engine):
        self.engine = engine

    def fetch_data(self):
        with self.engine.begin() as trans:
            rval = trans.execute("SELECT * FROM XXX")

test_a.py

import unittest
from unittest.mock import MagicMock, mock_open
from a import A


class TestA(unittest.TestCase):
    def test_fetch_data(self):
        engine_mock = MagicMock()
        trans = engine_mock.begin.return_value.__enter__.return_value
        trans.execute.return_value = 'fake data'
        a = A(engine_mock)
        a.fetch_data()
        engine_mock.begin.assert_called_once()
        trans.execute.assert_called_with("SELECT * FROM XXX")


if __name__ == '__main__':
    unittest.main()

具有100%覆盖率的单元测试结果:

.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
Name                                   Stmts   Miss  Cover   Missing
--------------------------------------------------------------------
src/stackoverflow/61224956/a.py            6      0   100%
src/stackoverflow/61224956/test_a.py      14      0   100%
--------------------------------------------------------------------
TOTAL                                     20      0   100%

python版本:Python 3.7.5

© www.soinside.com 2019 - 2024. All rights reserved.