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

9lowa7mx  于 2023-06-25  发布在  Python
关注(0)|答案(4)|浏览(105)

我是python新手,一直在使用python 3学习。我正在使用Python的单元测试框架来测试我的代码。
问题:-
我需要进行单元测试的函数以以下方式获取输入:

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

我使用下面的测试用例来模拟输入:

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")

我面临的问题是,当测试用例运行时,变量三元组a,b,c和d,e,f具有相同的值-1,2,3
我一直试图找到一种方法来注入第二组输入来运行我的测试,但没有成功。
任何有关上述的帮助是非常感谢。
解决方案环境:-Python 3

unftdfkk

unftdfkk1#

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

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

@patch("builtins.input", fake_input)
def test_compare(self):
    ...
3df52oht

3df52oht2#

补丁装饰器将确保打补丁的函数总是返回该值,如果后续调用必须不同,则mock对象必须有一种模拟方法。这最终会变得更加复杂。
但是,您可以做的是更低一步,修补底层,即标准输入/输出层。其他测试框架所采用的一个常见策略是直接处理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")

执行

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

OK

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

6qqygrtg

6qqygrtg3#

你不能像那样把你的功能修补两次。当你想模拟同一个函数,并让它在每次调用时返回不同的值时,你应该使用side_effect。
side_effect接受一个值列表,其中列表中的每个值都是代码中每次调用该函数时的返回值:

class TestCompare(unittest.TestCase):

    @patch("builtins.input", side_effect=["1 2 3", "4 5 6"])
    def test_compare(self, mock_input):
        self.assertEqual(compare(), "1 1")
uujelgoq

uujelgoq4#

Wim的回答是如此优雅,我不得不在我的代码库中尝试它,我想模拟类似于OP的顺序输入。我得到了方法 Package 器错误,不得不调整我的策略。下面是我编辑的Wim的替代品,我希望对其他任何人都能在这里找到自己的方式。

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

@patch("builtins.input", lambda _: next(fake_input))
def test_compare(self):
    ...

相关问题