title: Understanding with statement to catch ValueError in unittest class
body: <p>New to unittest and Python in general, came across example in a tutorial introduction to unit testing wherein a with statement is used to catch a ValueError. </p>
  
  <p>The script being tested (invoice_calculator.py) is: </p>
  
  <pre><code>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
  </code></pre>
  
  <p>The unit test includes this function in order to catch an edge case wherein <code>staff_hours = None</code> :</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>Regarding the use of the <code>with</code> statement in <code>test_zero_hours_total(self)</code>, what is actually happening here in terms of how this statement works/is being executed?</p>
  
  <p>Is the <code>test_zero_hours_total()</code> function basically working as follows (layman's description): the expected error should be <code>ValueError</code> (which we're doing by passing <code>ValueError</code> to the function <code>assertRaises()</code>) when <code>360.0, {"Alice": 0.0, "Bob": 0.0, "Carol": 0.0}</code> (which would raise a <code>ValueError</code> in <code>divide_pay()</code>) is passed as arguments to the <code>divide_pay()</code> function? </p>