Is it possible for a unit test to assert that a method calls sys.exit()?

Here's a complete working example. In spite of Pavel's excellent answer, it took me a while to figure this out, so I'm including it here in the hope that it will be helpful.

import unittest
from glf.logtype.grinder.mapping_reader import MapReader

INCOMPLETE_MAPPING_FILE="test/data/incomplete.http.mapping"

class TestMapReader(unittest.TestCase):

    def test_get_tx_names_incomplete_mapping_file(self):
        map_reader = MapReader()
        with self.assertRaises(SystemExit) as cm:
            tx_names = map_reader.get_tx_names(INCOMPLETE_MAPPING_FILE)
        self.assertEqual(cm.exception.code, 1)

Yes. sys.exit raises SystemExit, so you can check it with assertRaises:

with self.assertRaises(SystemExit):
    your_method()

Instances of SystemExit have an attribute code which is set to the proposed exit status, and the context manager returned by assertRaises has the caught exception instance as exception, so checking the exit status is easy:

with self.assertRaises(SystemExit) as cm:
    your_method()

self.assertEqual(cm.exception.code, 1)

 

sys.exit Documentation:

Exit from Python. This is implemented by raising the SystemExit exception ... it is possible to intercept the exit attempt at an outer level.


I found the answer to your question in the Python Unit Testing documentation search for "Testing for Exceptions". Using your example, the unit test would look like the following:

self.assertRaises(SystemExit, your_function, argument 1, argument 2)

Remember to include all arguments needed to test your function.


As an additional note to Pavel's excellent answer, you can also check for specific statuses if they're provided in the function you're testing. For example, if your_method() contained the following sys.exit("Error"), it would be possible to test for "Error" specifically:

with self.assertRaises(SystemExit) as cm:
    your_method()
    self.assertEqual(cm.exception, "Error")