2014-02-21 24 views
2

我試圖測試一個函數,我通過列表進行迭代,併爲列表中的每個項目調用os.path.exists。我的測試是將函數傳遞給2個對象的列表。我需要os.path.exists爲其中一個返回True,爲另一個返回False。我曾經嘗試這樣做:模擬/修補程序os.path.exists具有多個返回值

import mock 
import os 
import unittest 

class TestClass(unittest.TestCase): 
    values = {1 : True, 2 : False} 
    def side_effect(arg): 
     return values[arg] 

    def testFunction(self): 
     with mock.patch('os.path.exists') as m: 
      m.return_value = side_effect # 1 
      m.side_effect = side_effect # 2 

      arglist = [1, 2] 
      ret = test(argList) 

無論是使用而不是線的兩個#1和#2給出NameError: global name 'side_effect' is not defined

我發現這個question和修改我的代碼如下所示:

import mock 
import os 

class TestClass(unittest.TestCase): 
    values = {1 : True, 2 : False} 
    def side_effect(arg): 
     return values[arg] 

    def testFunction(self): 
     mockobj = mock(spec=os.path.exists) 
     mockobj.side_effect = side_effect 

     arglist = [1, 2] 
     ret = test(argList) 

這產生TypeError: 'module' object is not callable。 我還試圖切換這些行:

mockobj = mock(spec=os.path.exists) 
mockobj.side_effect = side_effect 

mockobj = mock(spec=os.path) 
mockobj.exists.side_effect = side_effect 

mockobj = mock(spec=os) 
mockobj.path.exists.side_effect = side_effect 

具有相同的錯誤被生產。任何人都可以指出我做錯了什麼,以及我能做些什麼來實現這個目標?

編輯: 發佈我的回答下面我意識到,我的代碼第一位實際工作爲好,我只是需要m.side_effect = TestClass.side_effect而不是m.side_effect = side_effect後。

回答

3

因此,經過多一點研究和試驗和錯誤,這裏的大多數例子:http://www.voidspace.org.uk/python/mock/patch.html,我解決了我的問題。

import mock 
import os 

def side_effect(arg): 
    if arg == 1: 
     return True 
    else: 
     return False 

class TestClass(unittest.TestCase): 
    patcher = mock.patch('os.path.exists') 
    mock_thing = patcher.start() 
    mock_thing.side_effect = side_effect 
    arg_list = [1, 2] 
    ret = test(arg_list) 
    self.assertItemsEqual([1], ret) 

test電話os.path.existarg_list每個項目,並返回os.path.exist退換True所有項目的列表。現在這個測試通過了我想要的方式。

+0

如果函數在兩個調用中具有相同的參數會怎樣? – hithwen

+0

你是什麼意思?如果'os.path.exists'傳遞給兩個調用的1?然後它會返回True,因爲這是副作用所說的。但是它不會被同一個參數傳遞兩次,因爲'test'函數遍歷'arg_list'併爲列表中的每個元素調用'os.path.exists'。所以只要列表中的兩個元素都不是「1」,那麼它將按預期工作。 –

+0

我的意思是,如果我想用相同的參數調用os.path.exists兩次,並返回第一個False,然後返回True。我想出瞭如何定義一個函數來計算被調用了多少次並返回不同的值並將其用作side_effect。 – hithwen

0

你可以做到self.side_effect我相信。因爲最初的定義不是全局的,所以在全局範圍內調用side_effect看看

相關問題