I'm wondering what is the best way to unittest a while loop that breaks only when a specific input is entered (see code for more detail). My test actually works as intended and fails correctly. However, I feel like it's 'hacked together' and isn't the best way to test this kind of code.
Currently, I have to manually break the loop within the test by mocking an user input that breaks the loop (see code for more detail). I've tried you parametrize in pytest, however, the test gets stuck on an infinite loop as soon as I mock an input that doesn't break the loop. It never gets to the next parametrized value.
Function Being Tested
def export_options():
while True:
try:
choice = int(input("\nPlease make a selection"))
if choice in range(1, 5):
return choice
else:
# I want to test this line when the input is bad
print("\nNot a valid selection\n")
except ValueError as err:
print("Please enter an integer")
Test Function
@mock.patch('realestate.app.user_inputs.print')
# The 1 is used to break the loop otherwise the test never ends!
@mock.patch('realestate.app.user_inputs.input', side_effect=[0, 5, 1])
def test_export_options_invalid_integer(mock_choice, mock_print):
user_inputs.export_options()
# Best way I could think of to test bad inputs. Anything that is less than 1 or greater than 4 will fail the test.
# Make sure I call the correct print function
mock_print.assert_called_with("\nNot a valid selection\n")
# Make sure I call the correct print function twice
assert mock_print.call_count == 2
I get the results I want based on my current code. However, I'd like to use best practices when possible and apply them to all future tests when dealing with while loops that only break based on a specific user input.