在Python中测试 - 如何在使用unittest的测试中使用assertRaises?

时间:2010-10-06 21:44:18

标签: python unit-testing testing exception-handling

我正在尝试使用unittest在Python中进行一个简单的测试,看看如果一个类在构造函数中获得不合适的输入时是否抛出异常。该课程如下:

class SummaryFormula:
    def __init__( self, summaryFormula):
        self.atoms = {}
        for atom in re.finditer( "([A-Z][a-z]{0,2})(\d*)", summaryFormula):
            symbol = atom.group(1)
            count = atom.group(2)

            if pocet != "":
                self.atoms[ symbol] = int(count)
            else:
                self.atoms[ symbol] = 1

我的测试如下:

    class ConstructorTestCase(unittest.TestCase):
      def testEmptyString(self):
        self.assertRaises(TypeError, ukol1.SummaryFormula(), "testtest")

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

我想要的只是测试失败,这意味着不处理构造函数的不合适输入的异常。

相反,我收到错误:__init__() takes exactly 2 arguments (1 given)

我错过了什么?我应该指定的第二个参数是什么?

此外,我应该使用什么类型的错误来处理异常,即我的regexp无法匹配的输入被传递给构造函数?

谢谢Tomas

5 个答案:

答案 0 :(得分:19)

assertRaises有点令人困惑,因为你需要给它调用它,而不是调用它的表达式。

将您的代码更改为:

self.assertRaises(TypeError, ukol1.SummaryFormula, "testtest")

在您的代码中,您自己调用构造函数,并且它引发了一个关于没有足够参数的异常。相反,您需要给assertRaises可调用的(ukol1.SummaryFormula),以及用它来调用它的参数(“testtest”)。然后它可以调用它,捕获并检查异常。

答案 1 :(得分:15)

更加pythonic的方法是使用with命令(在Python 2.7中添加):

with self.assertRaises(SomeException):
    do_something()

文档:https://docs.python.org/2/library/unittest.html#unittest.TestCase.assertRaises

答案 2 :(得分:13)

这是因为你的类在实例化对象时需要一个参数

当你传球时

ukol1.SummaryFormula()

你应该将参数summaryFormula传递给它。

ukol1.SummaryFormula(someSummaryFormula)

同样令人困惑的是你的类名是SummaryFormula,你传递给__init__的参数也是SummaryFormula

或者应该

self.assertRaises(TypeError, ukol1.SummaryFormula, "testtest")

答案 3 :(得分:3)

更通用的替代格式是

args=['testtest']
kwargs = {}
self.assertRaises(TypeError, ukol1.SummaryFormula, *args, **kwargs)

如果您的构造函数是多态的并且您希望循环遍历错误写入参数的不同方式的列表,这将非常有用,例如:

arg_lists = [
    ['testtest'],
    ['anothertest'],
    ['YAT'],
]
for args in arg_lists:
    self.assertRaises(TypeError, ukol1.SummaryFormula, *args)

答案 4 :(得分:1)

由于其他答案都没有指出如何使用封装导致异常的代码的上下文,这里是你如何做到的。

with self.assertRaises(ValueError) as ctx:
    <some code that throws an exception>

expected_msg = 'foo_bar_baz'
self.assertEquals(ctx.exception.message, expected_msg)

unittest.case._AssertRaisesContext中感兴趣的属性是:

  • 例外
  • 预期
  • expected_regexp
  • failureException