2013-08-10 12 views
5

Come si usa @patch decorator per applicare la patch alla funzione di input() integrata?Uso di unittest.mock per applicare patch input() in Python 3

Ad esempio, ecco una funzione in question.py che mi piacerebbe provare, che contiene una chiamata 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") 

Ecco la mia prova, che mi dà l'ImportError errore": No module named '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) 

risposta

8

__builtin__ modulo viene rinominato builtins in Python 3. Sostituire come segue:

@patch('builtins.input', lambda: 'y') 
+0

Non sembra funzionare con Python 3.5. –

+0

@IlanBiala, funziona per me: http://ideone.com/kdAjEd (testato su Python 3.5.1, Ubuntu 16.04 beta, Windows 7, semplificato per brevità) – falsetru

0

Oppure utilizzare l'attributo return_value di Mock. Non ho potuto farlo funzionare come decoratore, ma ecco come farlo con un contesto manager:

>>> 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 
>>> 
0

Per Python 2.x:

@patch('__builtin__.input') 

ha lavorato per me.

Problemi correlati