我有一个func1()函数,它正在生产中,不能修改。它调用另一个模块中的函数function_to_be_mocked()。它接受输入参数。
我还有另一个调用func1()的函数func2()。
我正在编写单元测试来测试func2(),并试图模拟function_to_be_mocked (因为它依赖于一些我在本地系统上没有(也不应该有)的键)。我唯一能修改的就是test_func2()。
我有一个如下所示的设置(最小示例):
from othermodule import function_to_be_mocked
import pytest
import mock
def func1():
function_to_be_mocked(None)
def func2():
ret = func1()
print (ret)
@mock.patch('othermodule.function_to_be_mocked', return_value = 3)
def test_func2(mocker):
func2()
othermodule.py是:
def function_to_be_mocked(arg1):
if not arg1 == 'foo':
raise ValueError
我的输出:
直接调用func2:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/blah/temp.py", line 9, in func2
ret = func1()
File "/Users/blah/temp.py", line 6, in func1
function_to_be_mocked(None)
File "/Users/blah/othermodule.py", line 3, in function_to_be_mocked
raise ValueError
ValueError
调用test_func2(),我希望它会被嘲笑:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/blah/venv/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
return func(*args, **keywargs)
File "/Users/blah/temp.py", line 14, in test_func2
func2()
File "/Users/blah/temp.py", line 9, in func2
ret = func1()
File "/Users/blah/temp.py", line 6, in func1
function_to_be_mocked(None)
File "/Users/blah/othermodule.py", line 3, in function_to_be_mocked
raise ValueError
ValueError
因此,模拟似乎不起作用。有没有人有什么想法可以做到这一点?
在此行===========下编辑的============
听起来我不能做我认为我能做的事情(因为我不能修改与函数1或2相关的任何东西。我唯一能控制的就是考试。
那么,让我提出以下问题,因为也许比我更有经验的眼睛可以看到前进的方向。
我有一个函数:
def function_to_be_tested(args):
# Some processing steps
# Function call that works locally
function_that_returns_something_1()
# Some logic
# Function call that works locally
function_that_returns_something_2()
# Function that raises an exception when running locally,
# and since I need to test the logic after this function
# (and cannot edit this code here to bypass it) I would
# (naively) like to mock it.
function_I_would_like_to_mock()
# Much more logic that follows this function.
# And this logic needs to be unit tested.
return some_value_based_on_the_logic
测试:
def test_function_to_be_tested():
assert function_to_be_tested(args) == some_expected_value
在function_I_would_like_to_mock()之前,我可以很容易地对任何东西进行单元测试。
但是由于这个函数在本地崩溃(我不能编辑代码来阻止它在本地崩溃),我觉得正确的方法应该是模拟它并强制一个合理的返回值。这样我就可以单元测试超出这个范围的代码路径了。
你建议什么是一个好的方法?
请注意,我唯一可以修改的是test函数。我甚至不能在主函数中添加装饰器。
发布于 2018-07-13 02:34:11
选项A)
您希望模拟的函数将加载到func1中。因此,您必须将@patch装饰器应用于func1
import pytest
from unittest import mock
@mock.patch('othermodule.function_to_be_mocked', return_value = 3)
def func1(mocker):
from othermodule import function_to_be_mocked
function_to_be_mocked(None)
def func2():
ret = func1()
print (ret)
def test_func2():
func2()
test_func2()
=========Edit===========
选项B)
import pytest
from unittest import mock
def func1():
from othermodule import function_to_be_mocked
function_to_be_mocked(None)
def func2():
ret = func1()
print (ret)
def test_func2():
with mock.patch('othermodule.function_to_be_mocked', return_value = 3) as irrelevant:
func2()
test_func2()
发布于 2022-02-26 03:46:24
如果你想模拟一个来自python中另一个模块中的模块内函数的函数,你可以试试这个。
# application2.py
def app2_func(a):
print(a)
# application1.py
import application2
def app1_func(a):
application2.app2_func(a) # func to be mocked
用于测试函数的测试文件
# application_test.py
import application1
def test_app1_func(mocker):
app2_mocker = mocker.patch('application1.application2.app2_func')
application1.app1_func('mock call')
app2_mocker.assert_called_once() # to check if mocked function is called once
https://stackoverflow.com/questions/51311935
复制相似问题