【问题标题】:Mock standard input - multi line in python 3模拟标准输入 - python 3中的多行
【发布时间】:2017-02-15 22:19:57
【问题描述】:

我是 python 新手,一直在使用 python 3 进行学习。我正在使用 python 的单元测试框架来测试我的代码。

问题:-

我需要进行单元测试的函数以下列方式接受输入:-

def compare():
   a, b, c = input().strip().split(' ')
   d, e, f = input().strip().split(' ')
   # other code here

我正在使用以下测试用例来模拟输入:-

class TestCompare(unittest.TestCase):

   @patch("builtins.input", lambda: "1 2 3")
   @patch("builtins.input", lambda: "4 5 6")
   def test_compare(self):
      self.assertEqual(compare(), "1 1")

我面临的问题是,当运行测试用例时,变量三元组 a、b、c 和 d、e、f 具有相同的值 - 1、2、3

我一直在尝试找到一种方法来注入第二组输入来运行我的测试,但没有成功。

非常感谢任何有关上述内容的帮助。

解决方案环境:- Python 3

【问题讨论】:

  • 我注意到您接受了我的回答,然后又接受了另一个(这从我的回答中删除了接受,这很好,只是想确保您知道)。您知道每个问题只能接受一个答案吗?
  • 哎呀..我很抱歉。实际上,您发布的一个和 wim 发布的一个都有效。我会记住,只能接受一个答案。感谢您指出这一点。

标签: python unit-testing python-3.x lambda patch


【解决方案1】:

你不能像那样修补两次。您必须修补一次,使用在后续调用中返回不同值的对象。这是一个例子:

fake_input = iter(['1 2 3', '4 5 6']).__next__

@patch("builtins.input", fake_input)
def test_compare(self):
    ...

【讨论】:

  • nit - 您的 def 存在标签问题
【解决方案2】:

补丁装饰器将确保补丁函数始终返回该值,并且如果后续调用必须不同,则您的模拟对象必须有一种方法来模拟它。这最终变得更加复杂。

但是,您可以做的就是降低一步并修补底层,即标准输入/输出层。其他测试框架采用的一种常见策略是直接处理sys.stdinsys.stdout 对象。考虑一下:

import unittest
from unittest.mock import patch

from io import StringIO

def compare():
    a, b, c = input().strip().split(' ')
    d, e, f = input().strip().split(' ')

    return '%s %s' % (a, d)

class TestCompareSysStdin(unittest.TestCase):

    @patch("sys.stdin", StringIO("1 2 3\n4 5 6"))
    def test_compare(self):
        self.assertEqual(compare(), "1 4")

执行

$ python -m unittest foo
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

自然,这在较低级别上工作,因此选择在后续调用中返回不同值的迭代器可能更合适。

【讨论】:

    【解决方案3】:

    你不能像那样两次修补你的函数。当您希望模拟同一个函数并让它每次调用时返回不同的值时,您应该使用side_effect

    side_effect 接受一个值列表,其中列表中的每个值都是代码中每次调用该函数时的返回值:

    class TestCompare(unittest.TestCase):
    
        @patch("builtins.input", side_effect=["1 2 3", "4 5 6"])
        def test_compare(self, mock_input):
            self.assertEqual(compare(), "1 1") 
    

    【讨论】:

      猜你喜欢
      • 2014-08-23
      • 2012-09-30
      • 2011-12-20
      • 2020-01-09
      • 2010-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多