Mock standard input - multi line in python 3
<p>I am new to python and have been using python 3 for my learning. I am using python's unit test framework to test my code.</p>

<p>Problem :-</p>

<p>The function that I need to unit test takes inputs in the following manner:-</p>

<pre><code>def compare():
   a, b, c = input().strip().split(' ')
   d, e, f = input().strip().split(' ')
   # other code here
</code></pre>

<p>I am using the following test case to mock the input :-</p>

<pre><code>class TestCompare(unittest.TestCase):

   @patch("builtins.input", lambda: "1 2 3")
   @patch("builtins.input", lambda: "4 5 6")
   def test_compare(self):
      self.assertEqual(compare(), "1 1")
</code></pre>

<p>The problem I am facing is that when the test case is run the variable triplets a,b,c and d,e,f have the same values - 1,2,3</p>

<p>I have been trying to find a way to inject the second set of inputs to run my test but in vain.</p>

<p>Any help regarding the above is greatly appreciated.</p>

<p>Solution environment :- Python 3</p>

<p>The patch decorator will ensure the patched function always return that value, and if subsequent calls must be different, your mock object must have a way to simulate that.  This ends up being much more complicated.</p>

<p>What you can do however is go one step lower and patch the underlying layer, which is the standard input/output layer.  One common strategy that other test frameworks have done is to deal with the <code>sys.stdin</code> and <code>sys.stdout</code> objects directly.  Consider this:</p>

<pre><code>import unittest
from unittest.mock import patch

from io import StringIO

def compare():
    a, b, c = input().strip().split(' ')
    d, e, f = input().strip().split(' ')

    return '%s %s' % (a, d)

class TestCompareSysStdin(unittest.TestCase):

    @patch("sys.stdin", StringIO("1 2 3\n4 5 6"))
    def test_compare(self):
        self.assertEqual(compare(), "1 4")
</code></pre>

<p>Execution</p>

<pre><code>$ python -m unittest foo
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
</code></pre>

<p>Naturally, this works at a lower level, and so the option to have an iterator that returns different values on subsequent calls may be more suitable.</p>

python unit-testing python-3.x lambda patch