1

so I have I'm practicing unit testing and I have the below code. I mock the input the first time and second time using side_effects but the assertion fails because the code is executing the else statement and not the intended output. Here is my run code.

def main():
    answer = input("Would you like to create a pirate?! (yes/no)").lower()

    if answer == 'y':

        name = input("Enter the name of your pirate")
        CreateAPirate(name, "Serpent", "100")

    elif answer == 'n':
        print("Okay! you chose not to create a pirate!")
    else:
        print("You must say Yes or No")


def CreateAPirate(name, ship, age, beard="NO"):
    print("Capt:", name)
    print("Pirate Ship:", ship)
    print("Age:", age)
    print("Do you have a beard?:", beard)
    return

here is my test code

import unittest
from unittest.mock import patch
import sys
from RunFile import main
import io

class TestSuite(unittest.TestCase):

    @patch('builtins.input',side_effects=['y','test'])
    def test_stdout_equals_Hello(self,m):

      saved_stdout = sys.stdout
      try:
          out = io.StringIO()
          sys.stdout = out
          main()
          output = out.getvalue().strip()
          self.assertEquals("Capt: test\nPirate Ship: Serpent\nAge: 100\nDo you have a beard?: NO",output)
      finally:
          sys.stdout = saved_stdout

if __name__ == "__main__":
    unittest.main()

and lastly my AssertionError code and traceback

Failure <Click to see difference>

Traceback (most recent call last):
  File "C:\Python33\lib\unittest\mock.py", line 1087, in patched
    return func(*args, **keywargs)
  File "C:\Users\jsalce\Documents\Testsuites\IfStatements\Testsuite.py", line 18, in     test_stdout_equals_Hello
    self.assertEquals("Capt: test\nPirate Ship: Serpent\nAge: 100\nDo you have a beard?: NO",output)
AssertionError: 'Capt: test\nPirate Ship: Serpent\nAge: 100\nDo you have a beard?: NO' != 'You must say Yes or No'
+ You must say Yes or No- Capt: test
- Pirate Ship: Serpent
- Age: 100
- Do you have a beard?: NO

I know whats wrong.. I just don't know how to fix it.

salce
  • 409
  • 1
  • 12
  • 28
  • possible duplicate of [python mocking raw input in unittests](http://stackoverflow.com/questions/21046717/python-mocking-raw-input-in-unittests) – Vor Sep 17 '14 at 19:25
  • That doesn't fix my issue. @Vor The the code is defaulting to the `else` statement. Not sure why if I mocked the first input as `'y'` – salce Sep 17 '14 at 21:27

1 Answers1

1

You are giving the first input the string 'yes' with side_effects but the conditional is testing specifically looking for the strings 'y' or 'n'.

You can make changes to builtins.input and it will work if you are fine with your captain also being named y. I do not think side_effects is the way to pass inputs in.

class TestSuite(unittest.TestCase):

    @patch('builtins.input')
    def test_stdout_equals_Hello(self,m):

      saved_stdout = sys.stdout
      try:
          out = io.StringIO()
          sys.stdout = out
          ori = __builtins__.input
          __builtins__.input = lambda x:'y'
          main()
          __builtins__.input = ori
          output = out.getvalue().strip()
          self.assertEquals("Capt: y\nPirate Ship: Serpent\nAge: 100\nDo you have a beard?: NO",output)
      finally:
          sys.stdout = saved_stdout
clm42
  • 65
  • 1
  • 9
  • `side_effect` should work fine. Reference this post http://stackoverflow.com/questions/25677260/python-unit-test-for-nested-if-statement `side_effect` patches `'y'` the first time input is called and `'test'` for the second time its called. – salce Sep 17 '14 at 21:30
  • Ah according to a comment on that post "you'd either need to adjust your test case to only assert that the text you care about is in the total output, rather than test for equality: self.assertIn("1.Scallywag\n2.Crew\n3.Pirate\nTEST", output)...". stdout is catching more than the just the result prints from main(). Ive not seen that done with side_effects before and will definitely use it in the future. – clm42 Sep 18 '14 at 12:33
  • I did what they said, but thats not my issue. Why is it registering the wrong input? It defaults to the else statement when it shouldn't. – salce Sep 18 '14 at 21:14
  • In the end it all comes back to that scourge, typos. side_effects should be side_effect. – clm42 Sep 19 '14 at 13:13