繁体   English   中英

为什么用 pytest-mock 模拟的方法不返回值?

[英]Why mocked method with pytest-mock does not return_value?

我在这里找到了一种更简洁的模拟方法的方法。 但是,当我运行 pytest 时,我得到

orig_width, orig_height = image_reader.getSize()

ValueError:没有足够的值来解包(预期 2,得到 0)

这是 test_tdd.py

def test_get_image_x1(mocker):
    """Test half size image."""
    # This works but it is longer
    class Mock_class:
        def __init__(self, *args):
            pass
        def getSize(self):
            return 1, 1
    mocker.patch("tdd.get_image.ImageReader", return_value=Mock_class())

    mocker.patch("tdd.get_image.Image")

    get_std_aspect_image(Path("tests/python-logo.png"), size="x 0.5")

    tdd.get_image.Image.assert_called_once_with(
        "tests/python-logo.png", width=0.5, height=0.5
    )


def test_get_image_x2(mocker):
    """Test half size image."""
    # This does not work
    mock_image_reader = mocker.patch("tdd.get_image.ImageReader")
    mock_image_reader.getSize.return_value = 1, 1

    mocker.patch("tdd.get_image.Image")

    get_std_aspect_image(Path("tests/python-logo.png"), size="x 0.5")

    tdd.get_image.Image.assert_called_once_with(
        "tests/python-logo.png", width=0.5, height=0.5
    )

test_get_image_x1 有效, test_get_image_x2 无效,因为 ImageReader.getSize 没有返回任何值

测试 function:

def get_std_aspect_image(file_name: Path, size: str = "x1"):
    """Return Image with original aspect and given width."""
    try:
        image_reader = ImageReader(str(file_name))
    except OSError:
        logging.critical("OS Error reading %s", file_name)
        raise

    orig_width, orig_height = image_reader.getSize()
    aspect = orig_height / float(orig_width)

    pattern = re.compile(r"(width|w|height|h|x)\s*(\d+\.\d+|\d+)", re.IGNORECASE)
    result = pattern.search(size)

    if result is not None:
        if result.groups()[0].lower() in ("w", "width"):
            width = float(result.groups()[1]) * mm
            return Image(
                str(file_name),
                width=width,
                height=(width * aspect),
            )
        elif result.groups()[0].lower() in ("h", "height"):
            height = float(result.groups()[1]) * mm
            return Image(
                str(file_name),
                width=height / aspect,
                height=height,
            )
        elif result.groups()[0].lower() == "x":
            factor = float(result.groups()[1])
            return Image(
                str(file_name),
                width=orig_width * factor,
                height=orig_height * factor,
            )

    raise ValueError

模拟的设置需要更紧密地匹配它的使用方式。 由于被测代码调用 ImageReader class,所以您也必须如此。

也就是说,而不是:

mock_image_reader.getSize.return_value = 1, 1
# do
mock_image_reader().getSize.return_value = 1, 1
#                ^^
# or more properly, use .return_value to avoid the class mock capturing the call eg.
mock_image_reader.return_value.getSize.return_value = 1, 1

mocking 代码对 class ImageReader 使用一个模拟,另一个模拟它生成的实例。 如果要指定“实例”模拟的行为,则需要使用().return_value来访问它。 否则,您指定 class 模拟的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM