模拟标准输入-python 3 中的多行

Shi*_*ven 1 python lambda unit-testing patch python-3.x

我是 python 新手,一直在使用 python 3 进行学习。我正在使用 python 的单元测试框架来测试我的代码。

问题 :-

我需要单元测试的函数以下列方式接受输入:-

def compare():
   a, b, c = input().strip().split(' ')
   d, e, f = input().strip().split(' ')
   # other code here
Run Code Online (Sandbox Code Playgroud)

我正在使用以下测试用例来模拟输入:-

class TestCompare(unittest.TestCase):

   @patch("builtins.input", lambda: "1 2 3")
   @patch("builtins.input", lambda: "4 5 6")
   def test_compare(self):
      self.assertEqual(compare(), "1 1")
Run Code Online (Sandbox Code Playgroud)

我面临的问题是,当测试用例运行时,变量三元组 a,b,c 和 d,e,f 具有相同的值 - 1,2,3

我一直试图找到一种方法来注入第二组输入来运行我的测试,但徒劳无功。

非常感谢有关上述任何帮助。

解决方案环境:- Python 3

wim*_*wim 5

你不能像那样修补两次。您必须修补一次,使用一个在后续调用中返回不同值的对象。下面是一个例子:

fake_input = iter(['1 2 3', '4 5 6']).__next__

@patch("builtins.input", fake_input)
def test_compare(self):
    ...
Run Code Online (Sandbox Code Playgroud)


met*_*ter 5

补丁装饰器将确保修补的函数始终返回该值,并且如果后续调用必须不同,则您的模拟对象必须有一种方法来模拟它。这最终会变得更加复杂。

然而,您可以做的是降低一步并修补底层,即标准输入/输出层。其他测试框架采用的一种常见策略是直接处理sys.stdinsys.stdout对象。考虑一下:

import unittest
from unittest.mock import patch

from io import StringIO

def compare():
    a, b, c = input().strip().split(' ')
    d, e, f = input().strip().split(' ')

    return '%s %s' % (a, d)

class TestCompareSysStdin(unittest.TestCase):

    @patch("sys.stdin", StringIO("1 2 3\n4 5 6"))
    def test_compare(self):
        self.assertEqual(compare(), "1 4")
Run Code Online (Sandbox Code Playgroud)

执行

$ python -m unittest foo
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
Run Code Online (Sandbox Code Playgroud)

当然,这在较低级别上工作,因此选择在后续调用中返回不同值的迭代器可能更合适。