2015-08-28 32 views
1

幾次我遇到了修飾器unittest.mock.patch的問題。當我嘗試從模塊中模擬單個功能時,patch不起作用。但是,如果從包含模塊的功能收集爲類方法,patch完美工作。蟒蛇模擬修補程序修飾器對於類方法和個別功能的行爲不同

部分地這question與我的相交。但是這個問題也沒有很好的答案。

這裏是什麼,我想描述一個例子:

|-- __init__.py 
|-- helpers.py 
|-- main_module.py 
|-- tests.py 

helpers.py寫一個函數作爲一個類的方法,而另一個作爲一個獨立的功能:

# helpers.py 
class HelperClass(): 

    def method_a(self): 
     return "a" 

def function_a(): 
    return "a" 

我已經將它們包括在主模塊中:

# main_module.py  
from helpers import HelperClass, function_a 


    def function_which_uses_helper_function(): 
     a_val = function_a() 
     return a_val 

    def function_which_uses_helper_class_method(): 
     a_val = HelperClass().method_a() 
     return a_val 

最後t EST序列:

# tests.py 
from unittest import TestCase 
from unittest.mock import patch 
from main_module import function_which_uses_helper_function, function_which_uses_helper_class_method 


class TestClass(TestCase): 

    @patch('helpers.function_a') 
    def test_function_which_uses_helper_function(self, mock_function_a): 
     mock_function_a.return_value = "c" 
     self.assertEqual(function_which_uses_helper_function(), "c") 

    @patch('helpers.HelperClass.method_a') 
    def test_function_which_uses_helper_class_method(self, mock_method_a): 
     mock_method_a.return_value = "c" 
     self.assertEqual(function_which_uses_helper_class_method(), "c") 

這給了我這些結果:

$ py.test tests.py 
<...> 
tests.py .F 
<...> 
tests.py:11: in test_function_which_uses_helper_function 
    self.assertEqual(function_which_uses_helper_function(), "c") 
E AssertionError: 'a' != 'c' 
E - a 
E + c 
============ 1 failed, 1 passed in 0.14 seconds ============ 

我感謝所有幫助。希望這也有助於某人:)

+1

如果您將類中的'function_a'重命名爲'method_a',它可能會清除一些事情。 – jonrsharpe

+0

感謝您的建議@jonrsharpe!完成。 – AnaPana

回答

1

過了一段時間,我終於明白爲什麼我的功能的例子沒有工作。解釋是here。而且this article也非常有用。考慮所有這些解決方案將是:

# main_module.py  
import helpers # <- I had to change my import statement 


def function_which_uses_helper_function(): 
    a_val = helpers.function_a() 
    return a_val 

def function_which_uses_helper_class_method(): 
    a_val = helpers.HelperClass().method_a() 
    return a_val 

另一種解決方案是改變我怎麼嘲笑我function_a的方式,那就是:

from unittest import TestCase 
from unittest.mock import patch 
from main_module import function_which_uses_helper_function, function_which_uses_helper_class 


class TestClass(TestCase): 

@patch('main_module.function_a') # <-- !!! I need to mock function in the`main_module`, not in `helpers` !!! 
def test_function_which_uses_helper_function(self, mock_function_a): 
    mock_function_a.return_value = "c" 
    self.assertEqual(function_which_uses_helper_function(), "c") 

@patch('helpers.HelperClass.function_a') 
def test_function_which_uses_helper_class(self, mock_function_a): 
    mock_function_a.return_value = "c" 
    self.assertEqual(function_which_uses_helper_class(), "c") 

我很傷心,我已經意識到了這一切剛剛。希望這有助於某人:)