I have a function to display a menu for users to input a selection. Based on the user selection, the program then calls separate functions. I am trying to write a test suite for my program and have been unable to pass any tests that would involve user-interaction, so I researched and discovered the Mock() module.
So far, I have been unable to find an example that is close enough to mine to help me in understanding how this would work for user input within a function or a module. I have found useful resources here and here but neither has enabled me to solve my issue. I also checked the forum here to see before asking and while there are topics that are similar (e.g. Python Mocking Raw Input in Unittests) still with my limited knowledge and the complexity of the task, I am having difficulties taking something I do not understand and applying it in a different way than I am seeing it.
The code I am hoping to test is:
import sys
def menu():
"""Display menu of options to toggle between to perform separate actions"""
selection_dict = {'A': func_A, 'B': func_B, 'C': func_C,
'D': func_D, 'E': quit_program, 'Q': quit_program}
while True:
selection = input('''
-- Menu Options --
A. Call Function A
B. Call Function B
C. Call Function C
D. Call Function D
E. Quit
Menu Selection: ''').upper()
print()
try:
selection_dict[selection]()
except ValueError:
print('Incorrect entry. Please enter A, B, C, D, or E.')
def func_A():
print('Function a')
menu()
def func_B():
print('Function b')
menu()
def func_C():
print('Function c')
menu()
def func_D():
print('Function d')
menu()
def func_E():
print('Function e')
menu()
sys.exit()
if __name__ == '__main__':
menu() # Program starts here
The test that I have tried so far (that fails) is:
from unittest import mock
from io import StringIO
import my_file as m
class Test_file(unittest.TestCase):
@mock.patch('sys.stdout', new_callable=StringIO)
def test_mock(self, tst_str, mock_stdout):
with mock.patch('builtins.input', side_effect=tst_str):
m.menu()
return mock_stdout.getvalue()
def test_entry(self):
self.assertEqual(self.test_mock(), 'Menu Options?')
if __name__ == '__main__':
unittest.main()