python-3.x PyTest如何正确模拟导入的ContextManager类及其功能?

5uzkadbs  于 2023-01-22  发布在  Python
关注(0)|答案(1)|浏览(148)

这是我的示例代码:

from path.lib import DBInterface

class MyClass:

    def __init__(self):
        self.something = "something"

    def _my_method(self, some_key, new_setup):
        with DBInterface(self.something) as ic:
            current_setup = ic.get(some_key)

        if current_setup != new_setup:
            with DBInterface(self.something) as ic:
                ic.set(new_setup)

    def public_method(self, some_key, new_setup):
        return self._my_method(some_key, new_setup)

(my实际的代码有点复杂,但我不能把它放在这里的公共:)
现在,我想做的是,我想完全模拟导入的类DBInterface,因为我不想让我的单元测试在DB中做任何事情。但是我还需要ic.get(some_key)返回一些值,或者更准确地说,我需要设置它返回的值,因为这是我的单元测试的重点,以测试方法是否根据DB返回的值正常工作。
这是我的进展:

class TestMyClass:

    def test_extractor_register(self, mocker):
        fake_db = mocker.patch.object('my_path.my_lib.DBInterface')
        fake_db.get.return_value = None
        # spy_obj = mocker.spy(MyClass, "_my_method")
        test_class = MyClass()

        # Test new registration in _extractor_register
        result = test_class.public_method(Tconf.test_key, Tconf.test_key_setup)
        fake_db.assert_has_calls([call().__enter__().get(Tconf.test_key),
                                  call().__enter__().set(Tconf.test_key, Tconf.test_key_setup)])
        # spy_obj.assert_called_with(ANY, Tconf.test_key, Tconf.test_key_setup)
        assert result.result_status.status_code == Tconf.status_ok.status_code
        assert result.result_data == MyMethodResult.new_reg

但是我无法设置call().__enter__().get(Tconf.test_key)的返回值。
我尝试了很多方法:

fake_db.get.return_value = None
fake_db.__enter__().get.return_value = None
fake_db.__enter__.get = Mock(return_value=None)
mocker.patch.object(MyClass.DBInterface, "get").return_value = None

所有这些都不起作用,我已经没有可想的选择了。

332nm8kg

332nm8kg1#

如果没有产生更多的代码或错误,很坚韧提供结论性的答案。
但是,如果您真的只需要为set()指定一个返回值,我建议使用MagicMock,因为patch--

from unittest.mock import patch

@patch("<MyClassFile>.DBInterface", autospec=True)
def test_extractor_register(mock_db):
        mock_db.set.return_value = "some key"
        # Rest of test code

相关问题