I am trying to simulate user input for a python script that I have going using py.test. Here's some basic code that represents what I'm trying to accomplish:
def ask():
while True:
age = input("Enter your age: ")
if int(age) < 13:
print("You are too young")
else:
name = input("Enter your name: ")
break
print("Welcome!")
I would like to mimic user input and read the output. An example might be something like:
@mock.patch('builtins.input', side_effect=['11'])
def test_invalid_age():
ask()
assert stdout == "You are too young"
I've also heard that flexmock might be a better alternative to the built-in unittest mocking system, but I'll take any solution at this point.
Update:
I played around a bit more and have a test that is this:
@mock.patch('builtins.input', side_effect=['11'])
def test_bad_params(self, input):
ask()
output = sys.stdout.getline().strip()
assert output == "You are too young"
When I run py.test I get this result:
E StopIteration /usr/lib/python3.3/unittest/mock.py:904:
StopIteration
It did catch capture the appropriate standard output call as "You are too young".
ask doesn't return after the first too-young age; it loops until an appropriate age is entered. As written, you'll need to supply all the strings it might read, then do all your assertions after ask returns.
@mock.patch('builtins.input', side_effect=['11', '13', 'Bob'])
def test_bad_params(self, input):
ask()
output = sys.stdout.getline().strip()
assert output == "You are too young"
# Check the output after "13" and "Bob" are entered as well!
assert sys.stdout.getline().strip() == "Welcome!"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With