简体   繁体   English

Python 单元测试 - mocking 导入模块/函数

[英]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进行单元测试,我需要模拟importedClassmyModule1.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM