0

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()
McBraunie
  • 107
  • 1
  • 12
  • The code you showed won't run at all. Can you create a [mcve] and add it to the question along with the error you get? – hoefling Jul 23 '18 at 07:11
  • I have updated the code to show the basic idea of what the menu is doing (the program is large and I have been chewed out on here before for providing _too_ much code. In reference to the unittest code, however, it is correct that it does not run as I am having difficulty in applying/understanding this concept. I was hoping that someone might be able to explain how it works (not do my work for me). – McBraunie Jul 23 '18 at 07:29
  • What is the purpose of `tst_str`? Do you want to write a test and then run it multiple times for different inputs? – hoefling Jul 23 '18 at 19:35

0 Answers0