Python MagicMock如何模拟__contains__方法

ghhaqwfi  于 2023-03-31  发布在  Python
关注(0)|答案(1)|浏览(92)

我已经定义了以下类:

class Config:

     def __init__(self) -> None:
        self._entries = dict()
 
    @property
    def entries(self):
        return self._entries
    
    def __contains__(self, key: any) -> bool:

        """
        Returns True if specified key is in the existing config
        entries, else returns False.
        """

        return key in self.entries

然后我有另一个类通过调用Config.__contains__

def some_function():
    config_obj = Config()
    if entry in config_obj:
        # Do something.

现在,我想对some_function和mock Config.__contains__进行单元测试。为此,我定义了这个测试函数:

from unittest.mock import MagicMock

def test_some_function()
    
    # given
    mocked_config_obj = Config()
    mocked_config_obj.__contains__ = MagicMock(return_value=True)
       
    # when
    some_function()

    # then
    mocked_config_obj.__contains__.assert_called_once() # Fails

理想情况下,if entry in config_obj应该调用mocked_config_obj.__contains__,但实际上没有。

bq3bfh9z

bq3bfh9z1#

您创建了一个MagicMock对象并将其赋值给一个名为mocked_config_obj的变量,但您从未为包含some_function的模块打补丁以使用该模拟对象。
假设我们有一个实现Config类的模块config.py

class Config:

    def __init__(self) -> None:
        self._entries = dict()

    @property
    def entries(self):
        return self._entries

    def __contains__(self, key: any) -> bool:

        """
        Returns True if specified key is in the existing config
        entries, else returns False.
        """

        return key in self.entries

以及实现SomeClass的模块some_module.py,它使用config.Config

from config import Config

class SomeClass:
    def some_function(self, entry):
        config_obj = Config()
        if entry in config_obj:
            print("doing something")

然后我们可以写一个像这样的测试:

from unittest import mock

import some_module

def test_some_function():
    with mock.patch('some_module.Config') as mock_config_obj:
        mock_config_obj.return_value.__contains__.return_value = True
        obj = some_module.SomeClass()
        obj.some_function("entry")

        mock_config_obj.return_value.__contains__.assert_called_with('entry')

这将安排config_obj = Config()接收一个mock对象,然后我们可以在some_function返回时测试调用。

相关问题