代码之家  ›  专栏  ›  技术社区  ›  radzak

从\ getattr \方法检索的模拟函数

  •  2
  • radzak  · 技术社区  · 6 年前

    我正在自动执行一些存储库操作,并且正在使用 GitPython 为了这份工作。让我们简化一些事情,假设我想断言我的函数是否调用 pull 存储库上的方法。代码如下:

    from pytest_mock import MockFixture
    from git import Git, Repo
    
    repo = Repo('/Users/Jatimir/path/to/repo')
    
    def pull() -> None:
        repo.git.pull()
    

    但是,我注意到 Git 类有点特殊,不实现 .相反,它将所有流量“委托”到 __getattr__ 它使用另一种方法来完成任务。

    def __getattr__(self, name):
        ...
        return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
    

    我的问题是如何进行测试?我在用 pytest 具有 pytest-mock 它提供了 mocker 我的尝试是:

    def test_pull1(mocker: MockFixture) -> None:
        pull_mock = mocker.MagicMock(name='pull')
        getattr_mock = mocker.MagicMock(name='__getattr__', return_value=pull_mock)
    
        mocker.patch.object(Git, '__getattr__', getattr_mock)
        pull()
        pull_mock.assert_called_once_with()
    
    
    def test_pull2(mocker: MockFixture) -> None:
        pull_mock = mocker.Mock(name='pull')
    
        def __getattr__(self, name):
            if name == 'pull':
                return pull_mock
    
        mocker.patch.object(Git, '__getattr__', __getattr__)
        pull()
        pull_mock.assert_called_once_with()
    

    它们都有效,但我觉得有更好的方法,也许我测试这一点的方法是错误的。

    1 回复  |  直到 6 年前
        1
  •  4
  •   radzak    6 年前

    jonrsharpe create

    def test_pull(mocker: MockFixture) -> None:
        m = mocker.patch.object(Git, 'pull', create=True)
        pull()
        m.assert_called_once_with()
    

    documentation 解释什么 create=True