简体   繁体   English

如何模拟与 Unittest 的数据库连接,用于连接作为上下文管理器的类?

[英]How to mock db connection with Unittest for class with connection as context manager?

Here it is class with one of it's methods running when class is initializing:这是在类初始化时运行其中一个方法的类:

class StatCollector:
    def __init__(self, poll_stat) -> None:
        self.polls = self.__get_polls()

    def __get_polls(self) -> Dict[str, Poll]:
        with pyodbc.connect(MSSQL_CONNECTION_PARAMS) as cnxn:
            polls = dict()
            cursor = cnxn.cursor()
            query = self.poll_stat.poll_ids_query_getter()
            cursor.execute(query, self.poll_stat.products_block)
            for poll in map(Poll._make, cursor.fetchall()):
                polls[poll.poll_id] = poll
        return polls

I want to test other methods of this class and my first goal is to fill self.polls with initial values with no real connection to db and using __get_polls method.我想测试这个类的其他方法,我的第一个目标是用初始值填充self.polls ,没有真正连接到 db 并使用__get_polls方法。 My try:我的尝试:

@patch("pyodbc.connect")
class testStatCollector(unittest.TestCase):
    def test_initial_values_setted(self, mock_connect):
        cursor = MagicMock(name="my_cursor")
        cursor.fetchall.return_value = [("2", "А", "B")]
        cnxn = MagicMock(name="my_cnxn_mfk")
        cnxn.cursor.return_value = cursor
        mock_connect.return_value.__enter__ = cnxn
        self.test_class = PollsStatCollector(IVR)
        self.assertEqual(
            self.test_class.polls, {"2": Poll("2", "A", "B")}
        )
        self.assertIsInstance(self.test_class.period_start_time, datetime)

But self.polls are empty after execution.但是self.polls执行后是空的。 I got: AssertionError: {} != {'2': Poll(poll_id='2', product='A', products_block='B')}我得到: AssertionError: {} != {'2': Poll(poll_id='2', product='A', products_block='B')}
and I see in debug, that cnxn name = my_cnxn_mfk when __get_polls executing, but then cursor with default name = <MagicMock name='my_cnxn_mfk().cursor()' id='1883689785424'> .我在调试中看到,当__get_polls执行时,cnxn name = my_cnxn_mfk ,但是光标的默认名称 = <MagicMock name='my_cnxn_mfk().cursor()' id='1883689785424'>
So i guess that i make mistake in this part cnxn.cursor.return_value = cursor , but i dont know how to fix it.所以我想我在这部分cnxn.cursor.return_value = cursor犯了错误,但我不知道如何修复它。

Mistake was here:错误在这里:

mock_connect.return_value.__enter__ = cnxn

Should be replaced with应该换成

mock_connect.return_value.__enter__.return_value = cnxn

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM