1

我想在我正在测试的周围函数的主体中模拟一个函数调用。我需要使用 flexmock 来做到这一点,或者至少知道它是否不可能。以下面这段代码为例。我有 3 个文件。utils.py 具有单个函数run_command,而 api.py 具有具有单个方法的类 test_api.py。所有这些都是出于演示目的,并不是特别有用,但应该能够描述我的问题

# util.py
import subprocess

def run_command(cmd):
    return subprocess.check_output(cmd)

现在 api.py 将使用 util.py 中的 run_command

# api.py
from util import run_comand


class Api:

    def get_update(self):
        result = run_command(["pwd"]).decode("utf-8")
        return f"Update: {result}"

现在我想为 Api.get_update 编写一个测试,但我不想实际执行 run_command

使用模拟模块,我会像这样编写测试

# test_api.py
from unittest import mock

@mock.patch("api.run_command")
def test_get_update(run_command_mock):
    run_command_mock.return_value = b"sucess!!!"
    api = Api()
    result = api.get_update()
    assert result == "Update: success!!!"

上述测试按预期工作。run_command它在被调用时实际上并没有执行get_update。它使用模拟版本。现在我想用 flexmock 来做这件事。我不知道这是否可能。只是我正在为一个项目做出贡献,并且所有测试都是用 flexmock 构建的,所以我想遵循相同的模式。不幸的是,我找不到解决类似问题的测试。从这个 SO mocking-functions-with-flexmock-in-python,我想出了这个

import utils as utils_module
import flexmock
from api import Api

def test_get_update():
    flexmock(utils_module).should_receive("run_command").with_args(["pwd"]).once().and_return("success!!")
    api = Api()
    result = api.get_update()
    assert result == "Update: success!!!"

上述测试失败。run_commandfrom utils 仍然执行,而不是我的模拟版本。如何使用 flexmock 解决此问题?

4

1 回答 1

0

我弄清楚我做错了什么。我在嘲笑run_command它来自哪里,而不是像我对@mock.patch. 为了修复它,我不得不像这样重写我的测试

import flexmock import flexmock
import api as api_module # Instead of importing utils, I'm importing api since that's where run_command is called even though it's coming from utils


def test_get_update():
    flexmock(api_module).should_receive("run_command").once().and_return(b"success!!!")
    api = api_module.Api()
    result = api.get_update()
    assert result == "Update: success!!!"
于 2020-04-05T09:50:46.873 回答