python - 我如何模拟执行 sys.exit() 的 Python 方法 OptionParser.error()?

标签 python unit-testing mocking optparse

我正在尝试对一些看起来像这样的代码进行单元测试:

def main():
    parser = optparse.OptionParser(description='This tool is cool', prog='cool-tool')
    parser.add_option('--foo', action='store', help='The foo option is self-explanatory')
    options, arguments = parser.parse_args()
    if not options.foo:
        parser.error('--foo option is required')
    print "Your foo is %s." % options.foo
    return 0

if __name__ == '__main__':
   sys.exit(main())

代码如下:

@patch('optparse.OptionParser')
def test_main_with_missing_p4clientsdir_option(self, mock_optionparser):
    #
    # setup
    #
    optionparser_mock = Mock()
    mock_optionparser.return_value = optionparser_mock
    options_stub = Mock()
    options_stub.foo = None
    optionparser_mock.parse_args.return_value = (options_stub, sentinel.arguments)
    def parser_error_mock(message):
        self.assertEquals(message, '--foo option is required')
        sys.exit(2)
    optionparser_mock.error = parser_error_mock

    #
    # exercise & verify
    #
    self.assertEquals(sut.main(), 2)

我正在使用 Michael Foord's Mock , 和 nose 来运行测试。

当我运行测试时,我得到:

  File "/Users/dspitzer/Programming/Python/test-optparse-error/tests/sut_tests.py", line 27, in parser_error_mock
    sys.exit(2)
SystemExit: 2

----------------------------------------------------------------------
Ran 1 test in 0.012s

FAILED (errors=1)

问题是 OptionParser.error 执行 sys.exit(2),因此 main() 自然依赖于它。但是 nose 或 unittest 检测到(预期的)sys.exit(2) 并未能通过测试。

我可以通过在 main() 中的 parser.error() 调用下添加“return 2”并从 parser_error_mock() 中删除 sys.exit() 调用来使测试通过,但我觉得修改代码很反感under test 允许测试通过。有更好的解决方案吗?

更新:df的答案有效,尽管正确的调用是“self.assertRaises(SystemExit, sut.main)”。

这意味着测试通过了 parser_error_mock() 中 sys.exit() 中的任何数字。有什么方法可以测试退出代码吗?

顺便说一句,如果我添加:

self.assertEquals(optionparser_mock.method_calls, [('add_option', ('--foo',), {'action': 'store', 'help': 'The foo option is self-explanatory'}), ('parse_args', (), {})])

最后。

更新 2:我可以通过将“self.assertRaises(SystemExit, sut.main)”替换为以下代码来测试退出代码:

try:
    sut.main()
except SystemExit, e:
    self.assertEquals(type(e), type(SystemExit()))
    self.assertEquals(e.code, 2)
except Exception, e:
    self.fail('unexpected exception: %s' % e)
else:
    self.fail('SystemExit exception expected')

最佳答案

这个可以代替 assertEquals 吗?

self.assertRaises(SystemExit, sut.main, 2)

这应该捕获 SystemExit 异常并防止脚本终止。

关于python - 我如何模拟执行 sys.exit() 的 Python 方法 OptionParser.error()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/426500/

相关文章:

python - 使用 cPickle 在 2.4 中 pickle array.array

python - Django:1045,“用户访问被拒绝

java - 单元测试离散傅里叶变换

python - Bokeh 悬停工具显示 '???' 而不是 ColumnDataSource 值

Python webdriver 库未连接到 chromedriver -- "Can not connect to the Service/usr/local/bin/chromedriver"

java - 如何配置 MockMvc 请求,它将作为我的 html 表单提交后发送的请求

java - 使用 Mockito 对 spring boot Controller 进行单元测试

c# - 我把我的模拟放在哪里?

ios - 如何从iOS单元测试中获取不同的info-plist?

unit-testing - 如何针对参数序列测试谓词?