2016-10-07 21 views
0

我是python的新手,並且一直在使用python 3進行學習。我正在使用python的單元測試框架來測試我的代碼。模擬標準輸入 - python中的多行3

問題: -

,我需要進行單元測試該函數採用輸入以下列方式: -

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

我使用下面的測試情況下嘲笑輸入: -

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") 

我面臨的問題是,當測試用例運行時,變量三元組a,b,c和d,e,f具有相同的值 - 1,2,3

我一直在試圖找到一種方法來注入第二組輸入來運行我的測試,但徒勞無益。

有關上述的任何幫助,不勝感激。

解決方案環境: - Python 3

+0

我注意到你接受了我的答案,然後接受了另一個(其中刪除接受我的回答,這很好,只是想確保你知道)。你是否知道每個問題只能接受一個答案? – idjaw

+0

哎呀..我很抱歉。實際上你發佈的和wim發佈的那兩個都有效。我會記住只有一個答案可以被接受。感謝您指出了這一點。 – Shiven

回答

2

補丁裝飾將確保打補丁函數始終返回值,如果後續調用必須是不同的,你的模擬對象必須有一種方法來模擬。這最終變得更加複雜。

然而,你可以做的是降低一個步驟並修補底層,這是標準的輸入/輸出層。其他測試框架所採取的一種常見策略是直接處理sys.stdinsys.stdout對象。試想一下:

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") 

執行

$ python -m unittest foo 
. 
---------------------------------------------------------------------- 
Ran 1 test in 0.000s 

OK 

當然,這個工作在一個較低的水平,所以選項有返回,在後續調用不同的值可能更適合的迭代器。

2

你不能這樣修補它兩次。您必須修補一次,並在隨後的調用中返回不同的值。這裏有一個例子:

fake_input = iter(['1 2 3', '4 5 6']).__next__ 

@patch("builtins.input", fake_input) 
def test_compare(self): 
    ... 
+0

nit - 你的'def'有一個tab鍵問題 – idjaw

+2

@idjaw thx - 下次自己編輯它吧 – wim

2

你不能像這樣兩次修補你的函數。當你想要模擬相同的功能,並在每次調用它時返回不同的值時,應該使用side_effect

side_effect取值,在列表中的每個值是每一個函數被調用你的代碼時,返回的列表:

class TestCompare(unittest.TestCase): 

    @patch("builtins.input", side_effect=["1 2 3", "4 5 6"]) 
    def test_compare(self, mock_input): 
     self.assertEqual(compare(), "1 1")