无法使用 mock_open() 在模拟函数中测试全局值
Unable to test a global value in a mocked function using mock_open()
我正在尝试使用 mock_open()
来测试我的应用程序 Mocking file reads using patch decorator and side_effect,但我无法检查 under 函数中的全局值集] 测试。它仅在函数返回值时有效。
我的应用程序代码片段类似于
#!/usr/bin/env python
# -*- coding: utf-8 -*-
thresh_dict = {}
allowed_san_dict = {}
max_eval_count = ""
clear_eval_count = ""
def generate_cfg_thresh_map():
""" For generating a mapping table containing the thresholds for each of the
production devices. The file is read one line at a time and split on whitespace
to get the individual fields
"""
global allowed_san_dict
global max_eval_count
global clear_eval_count
try:
with open ('/opt/config/pwr_thresh_cfg', 'r') as fh:
for line in fh:
split_line = line.split()
if line.startswith("ENTRY_THRESH_COUNT"):
max_eval_count = int(split_line[1])
elif line.startswith("EXIT_THRESH_COUNT"):
clear_eval_count = int(split_line[1])
else:
thresh_dict[split_line[0]] = [int(split_line[1]), int(split_line[2]), int(split_line[3])]
allowed_san_dict[split_line[0]] = int(split_line[4])
except Exception as error:
log_to_journal('read failed from pwr_thresh_cfg')
并且 test_app.py
文件看起来像
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Include require py.test libraries for the suite to run
import unittest
import pytest
import mock
import app
from mock import patch, mock_open
class ReportMonitor(unittest.TestCase):
def test_generate_cfg_thresh_map(self):
with patch('app.open', mock_open(read_data='ENTRY_THRESH_COUNT 200')) as _:
app.generate_cfg_thresh_map()
assert app.max_eval_count == 200
print('value for %s' % (app.max_eval_count))
print('value for %s' % (app.generate_cfg_thresh_map()))
问题是我想断言 generate_cfg_thresh_map()
函数中设置的 max_eval_count
的值。由于该值是在全局变量中设置的,而不是从函数返回的,所以我无法在我的测试用例中断言该值。我无法使用函数中的 return
,即根本不更改应用程序代码。
我该怎么做?即 运行 被测函数并检查函数为测试字符串设置的值,并根据函数设置的值断言单元测试用例。
引用 mock_open
docs:
read_data is a string for the read()
, readline()
, and readlines()
methods of the file handle to return. Calls to those methods will take data from read_data until it is depleted.
这意味着在迭代模拟文件对象时不会调用read_data
。一个简单的解决方法是将 generate_cfg_thresh_map
函数的实现更改为:
def generate_cfg_thresh_map():
...
try:
with open ('/opt/config/pwr_thresh_cfg', 'r') as fh:
<b>for line in fh.readlines():</b>
...
如果您不能更改函数,或者您可以增强 mock_open
返回的模拟对象:
Python 3
class ReportMonitor(unittest.TestCase):
def test_generate_cfg_thresh_map(self):
m = mock_open(read_data='ENTRY_THRESH_COUNT 200')
m.return_value.__iter__ = lambda self: self
m.return_value.__next__ = lambda self: next(iter(self.readline, ''))
with patch('app.open', m):
app.generate_cfg_thresh_map()
assert app.max_eval_count == 200
Python 2
class ReportMonitor(unittest.TestCase):
def test_generate_cfg_thresh_map(self):
m = mock_open(read_data='ENTRY_THRESH_COUNT 200')
m.return_value.__iter__ = lambda self: iter(self.readline, '')
with patch('app.open', m):
app.generate_cfg_thresh_map()
assert app.max_eval_count == 200
致谢:Customizing unittest.mock.mock_open for iteration.
我正在尝试使用 mock_open()
来测试我的应用程序 Mocking file reads using patch decorator and side_effect,但我无法检查 under 函数中的全局值集] 测试。它仅在函数返回值时有效。
我的应用程序代码片段类似于
#!/usr/bin/env python
# -*- coding: utf-8 -*-
thresh_dict = {}
allowed_san_dict = {}
max_eval_count = ""
clear_eval_count = ""
def generate_cfg_thresh_map():
""" For generating a mapping table containing the thresholds for each of the
production devices. The file is read one line at a time and split on whitespace
to get the individual fields
"""
global allowed_san_dict
global max_eval_count
global clear_eval_count
try:
with open ('/opt/config/pwr_thresh_cfg', 'r') as fh:
for line in fh:
split_line = line.split()
if line.startswith("ENTRY_THRESH_COUNT"):
max_eval_count = int(split_line[1])
elif line.startswith("EXIT_THRESH_COUNT"):
clear_eval_count = int(split_line[1])
else:
thresh_dict[split_line[0]] = [int(split_line[1]), int(split_line[2]), int(split_line[3])]
allowed_san_dict[split_line[0]] = int(split_line[4])
except Exception as error:
log_to_journal('read failed from pwr_thresh_cfg')
并且 test_app.py
文件看起来像
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Include require py.test libraries for the suite to run
import unittest
import pytest
import mock
import app
from mock import patch, mock_open
class ReportMonitor(unittest.TestCase):
def test_generate_cfg_thresh_map(self):
with patch('app.open', mock_open(read_data='ENTRY_THRESH_COUNT 200')) as _:
app.generate_cfg_thresh_map()
assert app.max_eval_count == 200
print('value for %s' % (app.max_eval_count))
print('value for %s' % (app.generate_cfg_thresh_map()))
问题是我想断言 generate_cfg_thresh_map()
函数中设置的 max_eval_count
的值。由于该值是在全局变量中设置的,而不是从函数返回的,所以我无法在我的测试用例中断言该值。我无法使用函数中的 return
,即根本不更改应用程序代码。
我该怎么做?即 运行 被测函数并检查函数为测试字符串设置的值,并根据函数设置的值断言单元测试用例。
引用 mock_open
docs:
read_data is a string for the
read()
,readline()
, andreadlines()
methods of the file handle to return. Calls to those methods will take data from read_data until it is depleted.
这意味着在迭代模拟文件对象时不会调用read_data
。一个简单的解决方法是将 generate_cfg_thresh_map
函数的实现更改为:
def generate_cfg_thresh_map():
...
try:
with open ('/opt/config/pwr_thresh_cfg', 'r') as fh:
<b>for line in fh.readlines():</b>
...
如果您不能更改函数,或者您可以增强 mock_open
返回的模拟对象:
Python 3
class ReportMonitor(unittest.TestCase):
def test_generate_cfg_thresh_map(self):
m = mock_open(read_data='ENTRY_THRESH_COUNT 200')
m.return_value.__iter__ = lambda self: self
m.return_value.__next__ = lambda self: next(iter(self.readline, ''))
with patch('app.open', m):
app.generate_cfg_thresh_map()
assert app.max_eval_count == 200
Python 2
class ReportMonitor(unittest.TestCase):
def test_generate_cfg_thresh_map(self):
m = mock_open(read_data='ENTRY_THRESH_COUNT 200')
m.return_value.__iter__ = lambda self: iter(self.readline, '')
with patch('app.open', m):
app.generate_cfg_thresh_map()
assert app.max_eval_count == 200
致谢:Customizing unittest.mock.mock_open for iteration.