【问题标题】:Test input message text and answer in Django custom admin command在 Django 自定义管理命令中测试输入消息文本和答案
【发布时间】:2018-06-20 23:38:17
【问题描述】:

我想在自定义管理命令中测试用户输入确认答案。该测试是针对显示给用户的消息和她输入的答案。

命令代码为:

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 建议使用模拟,但它是在一个孤独的环境中。我想测试用户输入以及可以添加到自定义命令中的其他内容。

什么是有效的方法?

【问题讨论】:

    标签: python django unit-testing


    【解决方案1】:

    在搜索了多个来源后,我找不到与我的问题类似的解决方案。所以我将其中的一些混合起来,使用 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上下文装饰器中的kwargreturn_value='Y'会模拟用户的回答,测试通过。

    【讨论】:

      猜你喜欢
      • 2016-03-28
      • 2011-08-15
      • 1970-01-01
      • 1970-01-01
      • 2015-05-15
      • 2018-06-19
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      相关资源
      最近更新 更多