首页 > 解决方案 > 模拟按顺序修补多个用户输入

问题描述

类似的问题已被问过很多次,但我似乎无法弄清楚我正在尝试构建的这个简单测试:我想先提供一个“y”,然后为需要用户输入的复杂函数提供一个“n” (即它需要按顺序输入两个输入)。这是我的尝试 - with 语句不会推进迭代器,但我不知道我将如何实现修补输入。

import mock

m = mock.Mock()
m.side_effect = ["y","n"]
    
@pytest.fixture(scope="module")
def test_my_complex_function():
    with mock.patch('builtins.input', return_value=m()):
        out = my_complex_function(some_args)
    return out

标签: pythontestingmocking

解决方案


如果我很好地理解了这个问题,那么您就有一个具有类似行为的功能。

模块.py

def complex_function():
    first = input("First input")
    second = input("Second input")
    return first, second

而且您想模拟input内置方法。你的方法是对的,唯一要解决的问题是你必须构建 2 个模拟。每个input实例一个。

测试模块.py

import pytest

from unittest.mock import Mock, patch

from module import complex_function

input_mock_y = Mock()  # First mock for first input call
input_mock_n = Mock()  # Second mock for second input call

input_mock = Mock()    # Combine the 2 mocks in another mock to patch the input call.
input_mock.side_effect = [input_mock_y.return_value, input_mock_n.return_value]

def test_my_complex_function():
    with patch('builtins.input', input_mock) as mock_input:
        result = complex_function()
    
    assert mock_method.call_count == 2

你可能会说:好的,但是我怎么知道每个输入都被正确地修补了呢?因此,您可以为任何输入模拟指定一些返回值,以便进行比较。

input_mock_y = Mock()
input_mock_y.return_value = "Y"

input_mock_n = Mock()
input_mock_n.return_value = "N"

input_mock = Mock()
input_mock.side_effect = [input_mock_y.return_value, input_mock_n.return_value]

def test_my_complex_function():
    with patch('builtins.input', input_mock) as mock_method:
        result = function()
    
    assert mock_method.call_count == 2
    assert result == ('Y', 'N')


推荐阅读