[英]Python unit tests - mocking imported modules / functions
I would like to mock some modules / functions for my unittests but I'm unable to manage it so far.我想为我的单元测试模拟一些模块/函数,但到目前为止我无法管理它。 I tried several ways to define the mocked values but I don't understand why they are not taken into accound.
我尝试了几种方法来定义模拟值,但我不明白为什么不考虑它们。
EDIT:编辑:
I made some new tests, following the advises presented in this other topic .我按照其他主题中提出的建议进行了一些新测试。
Here is a piece of code representing the application to test:这是代表要测试的应用程序的一段代码:
from services import myModule1
from services.spec1 import importedClass
class myClass(object):
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
self.param3 = 0
self.param4 = 0
self.myMethod()
def myMethod(self):
newVar = importedClass(**necessary_params)
self.param3 = newVar.meth1(self.param2)
calcParam = myModule1.methodMod1(self.param1)
self.param4 = calcParam["keyParam3"]
return
if __name__ == '__main__':
# Some piece of code
my_class = myClass(**any_params)
# Some piece of code
I would like to unit test myMethod
and I need to mock importedClass
and myModule1.methodMod1()
.我想对
myMethod
进行单元测试,我需要模拟importedClass
和myModule1.methodMod1()
。
Here is a new piece of code that I tried for the tests (I left the previous attempts afterwards).这是我为测试尝试的一段新代码(之后我放弃了之前的尝试)。
import unittest
from my_module import myClass
import services
def test_myClass(unittest.TestCase):
@patch('my_module.importedClass')
@patch('my_module.myModule1')
def test_myMethod(self, mock_mod1, mock_class):
mock_mod1.methodMod1.return_value = {"keyParam3": 5, "keyParam4": 7}
mock_class.meth1.return_value = 12
test_res= myClass(*test_parameters)
self.assertEqual(test_res.param3, 2)
self.assertEqual(test_res.param4, 5)
if __name__ == '__main__':
unittest.main()
It works sucessfully but the mocked values are not taken into account.它成功运行,但未考虑模拟值。
END EDIT结束编辑
Previous attempts:以前的尝试:
I assume the method / syntax will be the same, so I will present what I tried for each of them, showing 2 different approaches:我假设方法/语法是相同的,所以我将展示我对它们中的每一个所做的尝试,展示 2 种不同的方法:
import unittest
from my_module import myClass
import services
def test_myClass(unittest.TestCase):
def setUp(self):
services.spec1= Mock()
services.spec1.importedClass.meth1.return_value = 2
@patch('services.myModule1')
def test_myMethod(self, my_mock):
my_mock.methodMod1.return_value = {"keyParam3": 5, "keyParam4": 7}
test_res= myClass(*test_parameters)
self.assertEqual(test_res.param3, 2)
self.assertEqual(test_res.param4, 5)
if __name__ == '__main__':
unittest.main()
The result is that the calculated attributes are not updated and still 0 - so test fails I also tried to have 'only' services = Mock()
and defined return values for each part, to regroup each mock in setUp method or in a patch, but nothing worked.结果是计算出的属性没有更新,仍然是 0 - 所以测试失败我也尝试“只有”
services = Mock()
并为每个部分定义返回值,以在 setUp 方法或补丁中重新组合每个模拟,但没有任何效果。
I also tried a syntax with my_module.spec1= Mock()
, to make the functino global, or even self.spec1= Mock()
to make it very local to the test's context (if I understood correctly the differences, this is something I'm not really sure neither) but nothing worked.我还尝试了
my_module.spec1= Mock()
的语法,使 functino 成为全局的,甚至self.spec1= Mock()
使其在测试上下文中非常本地化(如果我理解正确的话,这是我的东西我也不太确定)但没有任何效果。
I feel I'm that far from a result but I'm not able to manage this test so far.我觉得我离结果还很远,但到目前为止我无法管理这个测试。
PS.附言。 To be complete,
necessary_params
is made of calculated values, the related sources is mocked as well - without any detail as they should not be significant in this test context.为了完整起见,
necessary_params
由计算值组成,相关来源也被模拟 - 没有任何细节,因为它们在这个测试上下文中不应该很重要。
To mock just the method:仅模拟方法:
class test_myClass(unittest.TestCase):
# @patch('my_module.importedClass') # Change this
@patch('my_module.importedClass.meth1') # to this
@patch('my_module.myModule1')
# def test_myMethod(self, mock_mod1, mock_class): # Change this
def test_myMethod(self, mock_mod1, mock_class_meth1): # to this
mock_mod1.methodMod1.return_value = {"keyParam3": 5, "keyParam4": 7}
# mock_class.meth1.return_value = 2 # Change this
mock_class_meth1.return_value = 2 # to this
test_parameters = (0, 0)
test_res = myClass(*test_parameters)
self.assertEqual(test_res.param3, 2)
self.assertEqual(test_res.param4, 5)
To mock the class and its method:模拟 class 及其方法:
https://docs.python.org/3/library/unittest.mock-examples.html#mocking-classes https://docs.python.org/3/library/unittest.mock-examples.html#mocking-classes
class test_myClass(unittest.TestCase):
@patch('my_module.importedClass')
@patch('my_module.myModule1')
def test_myMethod2(self, mock_mod1, mock_class):
mock_mod1.methodMod1.return_value = {"keyParam3": 5, "keyParam4": 7}
# mock_class.meth1.return_value = 2 # Change this
mock_class_instance = mock_class.return_value # to these
mock_class_instance.meth1.return_value = 2 # two lines
test_parameters = (0, 0)
test_res = myClass(*test_parameters)
self.assertEqual(test_res.param3, 2)
self.assertEqual(test_res.param4, 5)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.