以下方法的测试检查提示中的标准输出是否正确。
当调用"input()"时,它会等待用户按回车键并中断。测试通过自动按键"输入"通过。
这是黑客,必须有更好的方法来测试这种方法。
方法:
class GameDisplay:
@staticmethod
def prompt(text):
input_value = input(text)
return input_value
测试:
from pynput.keyboard import Key, Controller
class TestGameDisplay(unittest.TestCase):
@patch('sys.stdout', new_callable=StringIO)
def test_prompt_output(self, mock_stdout):
keyboard = Controller()
keyboard.press(Key.enter)
self.gameDisplay.prompt('Choose 0: ')
keyboard.release(Key.enter)
self.assertEqual( mock_stdout.getvalue(), 'Choose 0: ')
if __name__ == '__main__':
unittest.main()
输出:
由于按回车键而换行。
...................................
............................................
----------------------------------------------------------------------
Ran 79 tests in 0.113s
OK
测试修复尝试:
@patch('sys.stdout', new_callable=StringIO)
@patch('builtins.input', return_value='0')
def test_prompt_output(self, mock_stdout, input):
self.gameDisplay.prompt('Choose 0: ')
self.assertEqual( mock_stdout.getvalue(), 'Choose 0: ')
输出:
FAIL: test_prompt_output (tests.test_game_display.TestGameDisplay)
self.assertEqual( mock_stdout.getvalue(), 'Choose 0: ')
AssertionError: <MagicMock name='input.getvalue()' id='4675607744'> != 'Choose 0: '
----------------------------------------------------------------------
Ran 79 tests in 0.015s
FAILED (failures=1)
mock_stdout只捕获print
语句的stdout,因此请添加print(text)
class GameDisplay:
@staticmethod
def prompt(text):
input_value = input(text)
print(text)
return input_value
这段代码经过测试并按预期工作
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('__builtin__.input', return_value='0')
def test_prompt_output3(self, mock_input, mock_stdout):
p = GameDisplay.prompt('Choose 0: ')
self.assertEqual(p, '0')
self.assertEqual(mock_stdout.getvalue(), 'Choose 0: n')
但随后它会打印 选择 0:两次
测试prompt()
return_value在现实生活中应该足够了。
如果您真的想同时模拟输入和输出,则只剩下 1 个选项。
只要您不同时嘲笑print
就可以了:
print(text)
input_value = input()
或者采取疯狂的方式,假装标准:
mock_stdout = StringIO('Choose 0: ')
p = GameDisplay.prompt('Choose 0: ')
self.assertEqual(mock_stdout.getvalue(), 'Choose 0: ')
或者这类似于将return_value分配给模拟对象:
with mock.patch('sys.stdout', new=StringIO("xxx")) as mock_stdout: