理解with语句以捕获unittest类中的ValueError

Adj*_*con 4 python unit-testing with-statement python-2.7 python-unittest

单元测试和Python的新功能,在单元测试的教程介绍中遇到了示例,其中使用with语句来捕获ValueError.

正在测试的脚本(invoice_calculator.py)是:

def divide_pay(amount, staff_hours):
    """
    Divide an invoice evenly amongst staff depending on how many hours they
    worked on a project
    """
    total_hours = 0
    for person in staff_hours:
        total_hours += staff_hours[person]

    if total_hours == 0:
        raise ValueError("No hours entered")

    per_hour = amount / total_hours

    staff_pay = {}
    for person in staff_hours:
        pay = staff_hours[person] * per_hour
        staff_pay[person] = pay

    return staff_pay
Run Code Online (Sandbox Code Playgroud)

单元测试包括此功能,以便捕获边缘情况,其中staff_hours = None:

import unittest
from invoice_calculator import divide_pay

class InvoiceCalculatorTests(unittest.TestCase):
    def test_equality(self):
        pay = divide_pay(300.0, {"Alice": 3.0, "Bob": 6.0, "Carol": 0.0})
        self.assertEqual(pay, {'Bob': 75.0, 'Alice': 75.0, 'Carol': 150.0})

    def test_zero_hours_total(self):
        with self.assertRaises(ValueError):
            pay = divide_pay(360.0, {"Alice": 0.0, "Bob": 0.0, "Carol": 0.0})

if __name__ == "__main__":
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

关于with声明的使用,这个声明test_zero_hours_total(self)如何工作/正在执行的实际情况是什么?

test_zero_hours_total()基本工作职能如下:(外行的说明):预期的误差应该是ValueError(我们正在通过做传递ValueError给函数assertRaises()时)360.0, {"Alice": 0.0, "Bob": 0.0, "Carol": 0.0}(这将提高ValueErrordivide_pay())作为参数传递给传递divide_pay()函数?

mgi*_*son 9

我不是100%肯定你的问题在这里......

TestCase.assertRaises创建一个可以用作上下文管理器的对象(这就是它可以与with语句一起使用的原因).以这种方式使用时:

with self.assertRaises(SomeExceptionClass):
    # code
Run Code Online (Sandbox Code Playgroud)

上下文管理器的__exit__方法将检查传入的异常信息.如果缺少,AssertionError将抛出一个导致测试失败的方法.如果异常是错误的类型(例如,不是实例SomeExceptionClass),则AssertionError也会抛出异常.