2012-09-27 75 views
4

我需要修補os.listdir和其他os函數來測試我的Python函數。但是當它們被修補時,import語句失敗。是否有可能只在這個單一的模塊中修補這個函數,並且保持tests.py的正常工作?僅針對一個模塊使用Mock修補功能?

下面是打破import一個例子:

import os 
from mock import patch 

# when both isdir and isfile are patched 
# the function crashes 
@patch('os.path.isdir', return_value=False) 
@patch('os.path.isfile', return_value=False) 
def test(*args): 
    import ipdb; ipdb.set_trace() 
    real_function(some_arguments) 
    pass 

test() 

我想real_function看到修補os.path,並測試看正常功能。下面

here's the traceback

回答

4

您可以使用patch作爲一個上下文管理器,所以它僅適用於代碼with語句中:

import os 
from mock import patch 

def test(*args): 
    import ipdb; ipdb.set_trace() 
    with patch('os.path.isdir', return_value=False): 
     with patch('os.path.isfile', return_value=False): 
      real_function(some_arguments) 
    pass 

test() 
+0

這是一個好主意。其實,我可以創建自己的上下文管理器。 –

0

適合你需要的東西。注意我在測試運行之前和之後打印os.listdir只是爲了顯示所有內容都返回到正確的狀態。

import unittest, os 
from unittest import TestLoader, TextTestRunner 

def tested_func(path): 
    return os.listdir(path * 2) 

class Example(unittest.TestCase): 

    def setUp(self): 
     self._listdir = os.listdir 
     os.listdir = lambda p: ['a', 'b', 'a', 'b'] 

    def test_tested_func(self): 
     self.assertEqual(tested_func('some_path'), ['a', 'b', 'a', 'b']) 

    def tearDown(self): 
     os.listdir = self._listdir 

print os.listdir 
TextTestRunner().run(TestLoader().loadTestsFromTestCase(Example)) 
print os.listdir 
+0

你所提供的是模擬模塊的簡單的模擬,它不解決主要問題:os.listdir也被修補在其他代碼中,導入失敗。 –

0

您可以使用補丁作爲裝飾器在測試方法或測試類中。它使得代碼非常乾淨。注意修補過的對象被傳入測試方法。您可以在測試類級別執行相同的操作,並將模擬對象傳遞給每個測試方法。在這種情況下不需要使用setUp或tearDown,因爲這些都是自動處理的。

# module.py 
import os 

def tested_func(path): 
    return os.listdir(path * 2) 


# test.py 
from mock import patch 

@patch('module.os.listdir') 
def test_tested_func(self, mock_listdir): 
    mock_listdir.return_value = ['a', 'b'] 

    self.assertEqual(tested_func('some_path'), ['a', 'b', 'a', 'b']) 
    mock_listdir.assert_called_with('some_path' * 2) 

另請注意,您可以模擬要在要實際測試的模塊中打補丁的功能。

+0

您錯過了一點:修補os文件系統功能塊從修補後的代碼導入。 –

+0

你可以多發一些代碼,一個實際的破例嗎?因爲我不知道你從這個例子中得不到什麼效果。很想嘗試找到問題。 – aychedee

+0

而回溯將是有趣的 – aychedee