5

我有一个 python 项目,它使用 GitPython 对远程 Git 存储库执行克隆和拉取功能。

举个简单的例子:

import git
from git import Git
from git import Repo


def clone_and_checkout(full_dir, git_url, repo_ver):

    repo = Repo.clone_from(
        url=git_url,
        to_path=full_dir
    )

    # Trigger re-create if repository is bare
    if repo.bare:
        raise git.exc.InvalidGitRepositoryError

    # Set origin and pull
    origin = repo.remotes.origin
    origin.pull()

    # Check out desired version of repository
    g = Git(full_dir)
    g.checkout(repo_ver)

我希望能够为此功能编写一个单元测试,但显然这需要与当前的外部系统联系。

我很好奇是否有人以类似于使用 Mock 来模拟 HTTP 调用的方式模拟这种外部交互。我希望能够以一种可以在测试时模拟的方式执行这些任务,而无需调用实际的 Git 遥控器。

我应该如何为此编写测试?

编辑:为了更清楚我的要求,我应该提到我是 Mock 的新手,并且正在努力理解如何模拟这些类的实例而不是类本身。我的问题应该表述得更好——类似于“我如何使用 Mock 来设置实例特定的属性,比如裸?”

从那以后,我对 Mock 了解了很多,并想出了如何做到这一点,所以我将为我自己的问题提供一个答案。

4

1 回答 1

4

这似乎是对 Mock 的不完全理解,或者使用 Patch 方法的常见结果。

首先要做的是阅读位于 Mock 文档中的“修补位置”部分。有了这些信息,您应该能够使用 patch 函数来模拟上述函数中使用的 GitPython 对象。这些装饰器将出现在您的单元测试函数上方。

@mock.patch('gitter.Repo')
@mock.patch('gitter.Git')

为了为这些模拟对象之一的实例提供返回值,您可以使用PropertyMock。这是利用此功能的单元测试的完整示例:

import gitter  # file containing our clone function
import mock
import unittest


class test_gitter(unittest.TestCase):

    @mock.patch('gitter.Repo')
    @mock.patch('gitter.Git')
    def runTest(self, mock_git, mock_repo):

        # Set the "bare" attribute of the Repo instance to be False
        p = mock.PropertyMock(return_value=False)
        type(mock_repo.clone_from.return_value).bare = p

        gitter.clone_and_checkout(
            '/tmp/docker',
            'git@github.com:docker/docker.git',
            'master'
        )
        mock_git.checkout.called_once_with('master')
于 2015-09-06T21:51:19.477 回答