有没有办法在Python 2.7的unittest模块中模拟.strip()进行单元测试?

问题描述 投票:0回答:1

我正在使用 Python 2.7 进行编码项目。我很想切换到 Python 3,但不幸的是,我正在为一个程序编写脚本,该程序在 2.7 中只有一个 python 包,即使它有三分之一,我们的代码库切换也是不切实际的,所以这是不可能的。

我的代码涉及检查以字符串形式给出的路径是否存在,然后因为我不知道 os.path.exists 本身是否执行此操作,如果不存在,则会对文件名运行 .strip() 并尝试再次。

我正在尝试对此进行单元测试。我通过修补 os.path.exists 以返回 False 对其根本不存在进行了测试。但我不知道如何对 .strip() 之前返回 False、之后返回 True 的情况进行单元测试。

这是正在测试的函数的相关部分(if/elif/else 与单元测试相关):

import os

class Runner:
  def __init__(self, fname):
    self.fname = fname
  
  def input_check(self):
    if not os.path.exists(self.fname):
      self.fname = self.fname.strip()
      if not os.path.exists(self.fname):
        raise ValueError('input is not a valid path')
    if os.path.isfile(self.fname):
      self.ftype = 'file'
    elif os.path.isdir(self.fname):
      self.ftype = 'folder'
    else:
      raise ValueError('how is your input neither a file nor a folder??')

还有我尝试进行单元测试的两个示例: 示例1

import unittest
from mock import patch

class TestRunner(unittest.TestCase):
  @patch('.strip')
  @patch('os.path.exists')
  def test_input_check_exists_after_strip(self, patchexist, patchstrip):
    runner = Runner('test ')
    patchstrip.return_value = 'test'
    patchexist.return_value = False if runner.fname[-1] == ' ' else True
    with self.assertRaisesRegexp(ValueError, 'how is your input neither a file nor a folder??'):
      runner.input_check()

这个,似乎我不知道如何让它真正修补 .strip,而且我通过 Google 找到的答案似乎说没有办法修补某些内置函数(我也尝试过builtins.strip,也不起作用。)它说空模块名称或没有名为内置的模块。

示例2

import unittest
from mock import patch

class TestRunner(unittest.TestCase):
  @patch('os.path.exists')
  def test_input_check_exists_after_strip(self, patchexist):
    runner = Runner('test')
    patchexist.return_value = patchexist.called
    with self.assertRaisesRegexp(ValueError, 'how is your input neither a file nor a folder??'):
      runner.input_check()

此返回并显示“输入不是有效路径”ValueError。我猜测补丁的返回值在 input_check() 运行期间根本没有更新,即使对我来说不方便,这也是有意义的。

有没有办法测试这个?这是否有必要,或者 os.path.exists() 是否已经处理了无关的空白?我对单元测试还很陌生,甚至对模拟的概念也比较陌生,所以我将不胜感激。

python python-2.7 unit-testing python-unittest python-unittest.mock
1个回答
0
投票

使用
side_effect

对于

patchexist
,您可以使用
side_effect
代替
return_value
。这样,您可以在第一次调用
False
时返回
os.path.exists()
,并在第二次调用时返回
True
(在
strip()
之后)。 无需修补
strip()
功能。

下面我将向您展示测试代码(我使用Python 3而不是Python 2.7执行它),其中包含3个测试:

  • test_input_check_exists_after_strip()
    :文件
    test 
    和文件
    test
    不存在
  • test_file_exist_after_strip()
    :文件
    test 
    不存在,但文件
    test
    (在
    strip()
    之后)存在
  • test_directory_exist_after_strip()
    :文件
    test 
    不存在,但目录
    test
    (在
    strip()
    之后)存在
import unittest
from runner import Runner
from unittest.mock import patch
import os

class TestRunner(unittest.TestCase):

    @patch('os.path.exists')
    def test_input_check_exists_after_strip(self, patchexist):
        patchexist.side_effect = [False, False]
        runner = Runner('test ')
        with self.assertRaises(ValueError):
            runner.input_check()

    @patch('os.path.isfile')
    @patch('os.path.exists')
    def test_file_exist_after_strip(self, patchexist, patchisfile):
        patchexist.side_effect = [False, True]
        patchisfile.return_value = True
        runner = Runner('test ')
        runner.input_check()
        self.assertEqual('file', runner.ftype)

    @patch('os.path.isdir')
    @patch('os.path.isfile')
    @patch('os.path.exists')
    def test_directory_exist_after_strip(self, patchexist, patchisfile, patchisdir):
        patchexist.side_effect = [False, True]
        patchisfile.return_value = False
        patchisdir.return_value = True
        runner = Runner('test ')
        runner.input_check()
        self.assertEqual('folder', runner.ftype)

if __name__ == '__main__':
    unittest.main()

如果我在系统中执行测试,输出如下:

...
----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK
© www.soinside.com 2019 - 2024. All rights reserved.