Uso de unittest.mock para parchear la entrada () en Python 3

¿Cómo utiliza el decorador @patch para parchear la función incorporada de entrada ()?

Por ejemplo, aquí hay una función en question.py que me gustaría probar, que contiene una llamada a input ():

def query_yes_no(question, default="yes"): """ Adapted from http://stackoverflow.com/questions/3041986/python-command-line-yes-no-input """ valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} if default is None: prompt = " [y/n] " elif default == "yes": prompt = " [Y/n] " elif default == "no": prompt = " [y/N] " else: raise ValueError("invalid default answer: '%s'" % default) while True: sys.stdout.write(question + prompt) choice = input().lower() if default is not None and choice == '': return valid[default] elif choice in valid: return valid[choice] else: sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") 

Aquí está mi prueba, que me da el error “ImportError: Ningún módulo llamado ‘ builtins ‘”:

 import unittest from unittest.mock import patch import question class TestQueryYesNo(unittest.TestCase): @patch('__builtins__.input.return_value', 'y') def test_query_y(self): answer = question.query_yes_no("Blah?") self.assertTrue(answer) 

El módulo __builtin__ se renombra a incorporado en Python 3. Reemplace de la siguiente manera:

 @patch('builtins.input', lambda *args: 'y') 

ACTUALIZAR

input tiene un parámetro opcional. Se actualizó el código para aceptar el parámetro opcional.

O usa el atributo return_value de Mock. No pude hacerlo funcionar como decorador, pero a continuación se explica cómo hacerlo con un administrador de contexto:

 >>> import unittest.mock >>> def test_input_mocking(): ... with unittest.mock.patch('builtins.input', return_value='y'): ... assert input() == 'y' ... >>> def test_input_mocking(): ... with unittest.mock.patch('builtins.input', return_value='y'): ... assert input() == 'y' ... print('we got here, so the ad hoc test succeeded') ... >>> test_input_mocking() we got here, so the ad hoc test succeeded >>> 

Para Python 2.x:

 @patch('__builtin__.input') 

trabajó para mi.