当前位置: 首页 > 后端技术 > Python

Python3unittestmock.patchscope

时间:2023-03-25 21:50:39 Python

mock.patchscope在使用unittest.mock.patch之前,你必须阅读文档。你百度出来的例子肯定是最简单的例子,不说明补丁的条件,直接上官网写最简单的例子,如果你刚接触pythonunittest,可能还有大坑等着你。unittest官网文档关于patcher的第一句话很重要:patch装饰器用于仅在其装饰的功能范围内修补对象。即使出现异常,它们也会自动为您处理未打补丁的工作。所有这些函数也可以用在with语句中或用作类装饰器。Stackoverflow有一个更容易理解的答案:patch的工作原理是(暂时)将一个名称指向的对象更改为另一个名称。可以有许多指向任何单个对象的名称,因此要使修补工作,您必须确保修补被测系统使用的名称。基本原则是在查找对象的位置进行修补,该位置不一定与定义对象的位置相同。有的时候仔细看文档也是一个水平。我开始忽略第一句话,浪费了很多时间。让我用一个例子来说明补丁的范围:假设我在lib模块下有一个类FooclassFoo:defrun(self):return1然后我在api.bar#api中调用Foo().run()。py文件fromlibimportFoodefbar():instance=Foo()instance.run()让我们写bar测试用例:fromunittest.mockimportpatchfromapiimportbar@patch('lib.Foo')deftest_bar1(mock_foo):""""这是一个反例,mock并没有真正起作用"""instance=mock_foo.return_valueinstance.run.return_value=2print(bar().run())#return1assertbar().run()==2#False@patch('api.Foo')deftest_bar2(mock_foo):instance=mock_foo.return_valueinstance.run.return_value=2print(bar().run())#return2断言bar().run()==2#trueassertbar()isinstance请注意,test_bar1mock没有像我们预期的那样工作,Foo().run()仍然返回1,而test_bar2是我们预期的。test_bar1和test_bar2的区别在于test_bar1patch的target是lib.Foo,test_bar2patch的target是api.Footest_bar1和test_bar2唯一的区别是:@patch('lib.Foo')<==>@patch('api.Foo'),可以看出patch目标参数是在运行时替换目标,而不是替换源类