[Tutor] how to unittest cli input

Peter Otten __peter__ at web.de
Sun Oct 11 20:11:14 CEST 2015


Alex Kleider wrote:

> It'll take more studying on my part before I'll be able to implement
> Ben's suggestion.

I find Ben's example instructive, but when you're just starting you might 
prefer a simpler approach:

import unittest
from unittest import mock

import collect


class TestCollectData(unittest.TestCase):
    def test(self):
        with mock.patch(
                "builtins.input",
                side_effect=["foo", "bar", "baz"]):
            self.assertEqual(
                collect.collect_data(),
                dict(first="foo", last="bar", phone="baz"))


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


with mock.patch("builtins.input, side_effect=[...]):
    ...

temporarily replaces the built-in input() with a function that returns the 
first item in the side_effect list on the first call, then the second, and 
so on, something you could do by hand, only less conveniently:

>>> def input_many(): # example function; accumulate strings until ""
...     result = []
...     while True:
...         item = input()
...         if item == "": break
...         result.append(item)
...     return result
... 
>>> input_many()
foo
bar

['foo', 'bar']

Works ;) Now let's change input() to something that returns "one", then 
"two", then "":

>>> import builtins
>>> _input = builtins.input
>>> try:
...     builtins.input = lambda items=iter(["one", "two", ""]): next(items)
...     input_many()
... finally:
...     builtins.input = _input
... 
['one', 'two']




More information about the Tutor mailing list