我想在自定义管理命令中测试用户输入确认答案。该测试针对向用户显示的消息以及她输入的答案。
命令的代码是:
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('id', type=int)
def handle(self, *args, **options):
try:
experiment = Experiment.objects.get(pk=options['id'])
except Experiment.DoesNotExist:
raise CommandError(
'Experiment with id "%d" does not exist' % (options['id'])
)
answer = input('Are you sure? (Y/n)')
if answer == 'Y':
experiment.delete()
这个accepted answer建议使用 mock ,但这是在孤独的背景下。我想测试用户输入以及可以添加到自定义命令中的其他内容。
什么是有效的方法?
最佳答案
搜索多个来源后,我找不到与我的问题类似的解决方案。因此,我混合了其中一些,使用 python mock
库得到了一个简洁的解决方案。
测试方法(在test_commands.py中):
from unittest.mock import patch
# other imports
@patch('experiments.management.commands.remove_experiment.get_input',
return_value='Y')
def test_remove_experiment_displays_prompt_and_user_confirm_removing(
self, mock_user_input
):
experiment = create_experiment()
out = StringIO()
call_command(
'remove_experiment', experiment.id, stdout=out
)
self.assertEqual(mock_user_input.called, True)
(text,), kwargs = mock_user_input.call_args
self.assertEqual(text,
'All versions of experiment "%s" will be destroyed and cannot be '
'recovered. Are you sure? (Yes/n) ' % experiment.title)
self.assertFalse(Experiment.objects.exists())
现在,在命令类中,我们将 python input()
包装在我们的方法中(就像问题中提到的 accepted answer 中所做的那样)。
my_app.management.commands.remove_experiment:
def get_input(text):
return input(text)
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('id', type=int)
def handle(self, *args, **options):
try:
experiment = Experiment.objects.get(pk=options['id'])
except Experiment.DoesNotExist:
raise CommandError(
'Experiment with id "%d" does not exist' % (options['id'])
)
answer = get_input('Are you sure? (Y/n)')
if answer == 'Y':
experiment.delete()
现在,测试将验证问题文本,在用户输入提示中是否正确,但不会将其显示在 stdout
中。此外,@patch
上下文装饰器中的kwarg return_value='Y'
将模拟用户答案,并且测试通过。
关于python - 在 Django 自定义管理命令中测试输入消息文本和答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48210488/