如何使用 mock to return None 来解析已知参数?
How can I use mock to return None for parse known args?
下面我有一个函数 returns 基于命令行输入的两个日期。我如何使用mock来制作它以便我可以对else语句进行单元测试?
# time from of pull
def time_frame():
"""
checks for optional user input for start and end date of data pull
creates start and end date for query
:return: start and end date
"""
# get the dates
args, leftovers = get_the_args()
if args.start_dt is not None and args.end_dt is not None:
return args.start_dt, args.end_dt
else:
# get today
the_today_start_date, the_today_end_date = get_dates_from_today()
return the_today_start_date, the_today_end_date
我尝试使用 mock_get_the_args.return_value = mock.Mock(return_value=None), mock.Mock()
使 get_the_args()
函数的 args 输出 returns None 当我的单元测试的这一部分运行时?我需要更改代表 args
变量的 mock.Mock() 什么才能使它起作用?
以下是到目前为止的单元测试:
# the time frame
@mock.patch('src.toolkit.get_dates_from_today')
@mock.patch('src.toolkit.get_the_args')
def test_time_frame(mock_get_the_args, mock_get_dates_from_today):
# set some dates
start_date = '2019-01-01'
end_date = '2019-01-01'
# mocking
mock_get_the_args.return_value = mock.Mock(), mock.Mock()
mock_get_dates_from_today.return_value = mock.Mock(), mock.Mock()
start_date, end_date = time_frame()
mock_get_the_args.assert_called_once()
mock_get_the_args.return_value = mock.Mock(return_value=None), mock.Mock()
start_date, end_date = time_frame()
mock_get_dates_from_today.assert_called_once()
使用 argparse
代码进行单元测试有点棘手,因为它通常需要来自命令行的输入。但是测试本身使用命令行(可能使用它自己的 argparse 解析器)。
我假设 get_the_args
设置了一个解析器,并且 returns parser.parse_known_args()
.
出于测试目的,您可以方便地选择提供明确的 argv
列表。
例如:
def time_frame(argv=None):
"""
checks for optional user input for start and end date of data pull
creates start and end date for query
:return: start and end date
"""
# get the dates
args, leftovers = get_the_args(argv)
...
其中 get_the_args
使用 parse_known_args(argv)
.
如果argv
是None,那么它会解析常规命令行。但是您可以提供生成所需 args
和 extras
的任何字符串列表。实际上,您可以模拟命令行。
另一种选择是定义一个 args
命名空间对象,例如。 args = argparse.Namespace(start_dt=None, end_dt='foobar')
。然后你可以像以前一样使用args.start_dt
。
使测试更容易的另一件事是仅当代码 运行 作为脚本时才使 parser
为 运行,而不是在导入时。即放在`if name =='main': block.
下面我有一个函数 returns 基于命令行输入的两个日期。我如何使用mock来制作它以便我可以对else语句进行单元测试?
# time from of pull
def time_frame():
"""
checks for optional user input for start and end date of data pull
creates start and end date for query
:return: start and end date
"""
# get the dates
args, leftovers = get_the_args()
if args.start_dt is not None and args.end_dt is not None:
return args.start_dt, args.end_dt
else:
# get today
the_today_start_date, the_today_end_date = get_dates_from_today()
return the_today_start_date, the_today_end_date
我尝试使用 mock_get_the_args.return_value = mock.Mock(return_value=None), mock.Mock()
使 get_the_args()
函数的 args 输出 returns None 当我的单元测试的这一部分运行时?我需要更改代表 args
变量的 mock.Mock() 什么才能使它起作用?
以下是到目前为止的单元测试:
# the time frame
@mock.patch('src.toolkit.get_dates_from_today')
@mock.patch('src.toolkit.get_the_args')
def test_time_frame(mock_get_the_args, mock_get_dates_from_today):
# set some dates
start_date = '2019-01-01'
end_date = '2019-01-01'
# mocking
mock_get_the_args.return_value = mock.Mock(), mock.Mock()
mock_get_dates_from_today.return_value = mock.Mock(), mock.Mock()
start_date, end_date = time_frame()
mock_get_the_args.assert_called_once()
mock_get_the_args.return_value = mock.Mock(return_value=None), mock.Mock()
start_date, end_date = time_frame()
mock_get_dates_from_today.assert_called_once()
使用 argparse
代码进行单元测试有点棘手,因为它通常需要来自命令行的输入。但是测试本身使用命令行(可能使用它自己的 argparse 解析器)。
我假设 get_the_args
设置了一个解析器,并且 returns parser.parse_known_args()
.
出于测试目的,您可以方便地选择提供明确的 argv
列表。
例如:
def time_frame(argv=None):
"""
checks for optional user input for start and end date of data pull
creates start and end date for query
:return: start and end date
"""
# get the dates
args, leftovers = get_the_args(argv)
...
其中 get_the_args
使用 parse_known_args(argv)
.
如果argv
是None,那么它会解析常规命令行。但是您可以提供生成所需 args
和 extras
的任何字符串列表。实际上,您可以模拟命令行。
另一种选择是定义一个 args
命名空间对象,例如。 args = argparse.Namespace(start_dt=None, end_dt='foobar')
。然后你可以像以前一样使用args.start_dt
。
使测试更容易的另一件事是仅当代码 运行 作为脚本时才使 parser
为 运行,而不是在导入时。即放在`if name =='main': block.