模拟标准输入 - python 3 中的多行
Mock standard input - multi line in python 3
我是 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
你不能那样修补它两次。您必须使用一个在后续调用中 returns 不同值的对象对其进行一次修补。这是一个例子:
fake_input = iter(['1 2 3', '4 5 6']).__next__
@patch("builtins.input", fake_input)
def test_compare(self):
...
补丁装饰器将确保补丁函数始终 return 该值,如果后续调用必须不同,您的模拟对象必须有办法模拟该值。这最终变得更加复杂。
然而,您可以做的是再向下一层修补底层,即标准 input/output 层。其他测试框架所做的一种常见策略是直接处理 sys.stdin
和 sys.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
当然,这在较低级别上有效,因此选择在后续调用中具有 return 不同值的迭代器可能更合适。
你不能像那样修补你的函数两次。当你想模拟同一个函数,并在每次调用它时让它 return 不同的值,你应该使用 side_effect.
side_effect
获取一个值列表,其中列表中的每个值都是在您的代码中每次调用该函数时的 return:
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")
我是 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
你不能那样修补它两次。您必须使用一个在后续调用中 returns 不同值的对象对其进行一次修补。这是一个例子:
fake_input = iter(['1 2 3', '4 5 6']).__next__
@patch("builtins.input", fake_input)
def test_compare(self):
...
补丁装饰器将确保补丁函数始终 return 该值,如果后续调用必须不同,您的模拟对象必须有办法模拟该值。这最终变得更加复杂。
然而,您可以做的是再向下一层修补底层,即标准 input/output 层。其他测试框架所做的一种常见策略是直接处理 sys.stdin
和 sys.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
当然,这在较低级别上有效,因此选择在后续调用中具有 return 不同值的迭代器可能更合适。
你不能像那样修补你的函数两次。当你想模拟同一个函数,并在每次调用它时让它 return 不同的值,你应该使用 side_effect.
side_effect
获取一个值列表,其中列表中的每个值都是在您的代码中每次调用该函数时的 return:
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")