2015-08-28 31 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") 

我很伤心,我已经意识到了这一切刚刚。希望这有助于某人:)