Skip to content

Instantly share code, notes, and snippets.

@fgui
Created April 17, 2016 07:43
Show Gist options
  • Save fgui/e84a978ddbe9982bec0d35575dbe9d43 to your computer and use it in GitHub Desktop.
Save fgui/e84a978ddbe9982bec0d35575dbe9d43 to your computer and use it in GitHub Desktop.
playing with being able to mock multiple inputs (I am sure there other/better ways to do this)
def makeMultiInput(inputs, idx=0):
'inputs a collection of strings, to be returned one at a time'
# closure on inputs and index
def next_input(message=""):
# nonlocal only in python3 similar to global but
# for non local non global variables
nonlocal idx
if idx < len(inputs):
idx = idx + 1
return inputs[idx - 1]
else:
return ""
return next_input
def test_multi_input_closure():
multi_input = makeMultiInput(["foo", "bar"])
assert (multi_input("message") == "foo")
assert (multi_input() == "bar")
assert (multi_input("message") == "")
# small function to test mocking multiple input requests
def echo_till_empty():
data = input("?")
while data != "":
print (data)
data = input("?")
def test_echo_till_empty(monkeypatch, capsys):
monkeypatch.setitem(__builtins__, 'input',
makeMultiInput(["1", "two", "III"]))
echo_till_empty()
out, err = capsys.readouterr()
assert out == "1\ntwo\nIII\n"
@tjcim
Copy link

tjcim commented Oct 25, 2017

Thanks for posting this. It was very helpful. I ended up with this using pytest:

def make_multiple_inputs(inputs):
    """ provides a function to call for every input requested. """
    def next_input(_):
        """ provides the first item in the list. """
        return inputs.popleft()
    return next_input

def test_functional(capfd, monkeypatch):
    """ Does a functional test of the script. """
    monkeypatch.setitem(__builtins__, 'input', make_multiple_inputs(
        deque(["one", "two", "three", "four"])))
    module.main()
    out, _ = capfd.readouterr()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment