Python 模拟失败调用断言

标签 python unit-testing mocking

我一直在阅读 python 模拟,但无法理解为什么以下代码失败。

我有两个类,一个 Potato 和一个 PotatoBag ,如下所示。 Figure 存储在 food.py 中,Report 存储在 bag.py 中。

class Potato:
    def create_potato(self):
        pass

    def output_potato(self):
        pass


class PotatoBag:
    def __init__(self, potatoes):
        self.potatoes = potatoes

    def output_to_file(self):
        for fig in self.potatoes:
            fig.create_potato()
            fig.output_potato()

目前,我正在尝试对输出方法进行单元测试,以便 Report 使用模拟正确地从 Figure 调用 create_figureoutput_figure 。这是我的测试代码:

from unittest.mock import MagicMock, patch
from bag import PotatoBag
from food import Potato
import pytest

@pytest.fixture(scope='module')
def potatoes():
    x = Potato()
    y = Potato()
    return [x, y]

@patch('food.Potato')
def test_output_to_file(mock_potato, potatoes):

    test_potato_bag = PotatoBag(potatoes)
    test_potato_bag.output_to_file()

    mock_potato.return_value.create_potato.assert_called()
    mock_potato.return_value.output_potato.assert_called()

pytest 立即产生一个 AssertionError ,表明 create_figure 从未被调用。

_mock_self = <MagicMock name='Potato().create_potato' id='140480853451272'>

    def assert_called(_mock_self):
        """assert that the mock was called at least once
            """
        self = _mock_self
        if self.call_count == 0:
            msg = ("Expected '%s' to have been called." %
                   self._mock_name or 'mock')
>           raise AssertionError(msg)
E           AssertionError: Expected 'create_potato' to have been called.

/home/anaconda3/lib/python3.7/unittest/mock.py:792: AssertionError

我的代码有什么问题吗?

最佳答案

您正在向报告传递来自您的装置的图形列表,而不是模拟。

将您的测试更改为...

@patch('figure.Figure')
def test_output_to_file(mock_figure, figures):

    test_report = Report([mock_figure])
    test_report.output_to_file()

    mock_figure.create_figure.assert_called_once()
    mock_figure.output_figure.assert_called_once()

这解决了测试 output_to_file 正确调用 Figure 上的函数的问题,而无需实际担心设置图形并处理可能带来的任何副作用或额外复杂性调用这些函数。可以在 Figure 的单元测试中省去这种担忧;)

关于Python 模拟失败调用断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53809388/

相关文章:

python - 删除字符串中除第一次出现以外的所有出现

unit-testing - 将单元测试用例的 Private 方法更改为 Public 是一个很好的做法

python - 无法在 Windows 上使用 Python 模拟操作系统名称

python - “函数”对象没有属性 'assert_called_once_with'

asp.net-mvc - ASP.Net RC1 中 TryUpdateModel 的模拟要求

python - 使用 Python 刷新 Tableau 仪表板

python - 成功在Azure部署Flask应用程序,但应用程序在打开网站时无法运行

Python:防止字典的键被覆盖

c - 模拟/伪造文件系统以测试 C 代码?

c# - 如何在 visual studio 之外对项目进行单元测试