我有一个小的 python3 脚本。像这样的东西
import sys
content = sys.stdin.read()
print(content)
我需要使用 import unittest 为此编写一个单元测试。我想了解如何使用单元测试模拟标准输入。
我找到了一些文章这里
和here,但我仍然无法处理它,因为在我运行测试脚本后,程序期望我提供标准输入。
你能帮我重写这段代码(或编写另一个)来测试我的脚本吗
import unittest
from unittest.mock import patch
import module_under_test
class MyTestCase(unittest.TestCase):
def setUp(self):
# raw_input is untouched before test
assert module_under_test.raw_input is __builtins__.raw_input
def test_using_with(self):
input_data = "123"
expected = int(input_data)
with patch.object(module_under_test, "raw_input", create=True,
return_value=expected):
# create=True is needed as raw_input is not in the globals of
# module_under_test, but actually found in __builtins__ .
actual = module_under_test.function()
self.assertEqual(expected, actual)
@patch.object(module_under_test, "raw_input", create=True)
def test_using_decorator(self, raw_input):
raw_input.return_value = input_data = "123"
expected = int(input_data)
actual = module_under_test.function()
self.assertEqual(expected, actual)
def tearDown(self):
# raw input is restored after test
assert module_under_test.raw_input is __builtins__.raw_input
if __name__ == "__main__":
unittest.main()
patch
: 的测试方法
script.py
:
import sys
def main() -> None:
content = sys.stdin.read()
print(content)
if __name__ == '__main__':
main()
script_test.py
:
import unittest
from unittest.mock import patch
import script
class ScriptTest(unittest.TestCase):
@patch('sys.stdin.read')
def test_content_reading(self, mock_stdin):
mock_stdin.return_value = 'mocked data 123'
with patch('builtins.print') as mock_print:
script.main()
mock_print.assert_called_once_with('mocked data 123')
if __name__ == '__main__':
unittest.main()
用法示例:
$ python -m unittest script_test.py
.
----------------------------------------------------------------------
Ran 1 test in 0.032s
OK
注意。使用
sys.stdin.read()
时。它等待 EOF(文件结束)来读取内容。如果您在终端中测试它,则可以通过按 Linux/macOS 上的 Ctrl-D
或 Windows 上的 Ctrl-Z
来表示 EOF。