20

It seems that python nosetest will quit when encountered sys.exit(), and mocking of this builtin doesn't work.

Bonifacio2
  • 3,405
  • 6
  • 34
  • 54
Hailiang Zhang
  • 17,604
  • 23
  • 71
  • 117

5 Answers5

41

You can try catching the SystemExit exception. It is raised when someone calls sys.exit().

with self.assertRaises(SystemExit):
  myFunctionThatSometimesCallsSysExit()
kichik
  • 33,220
  • 7
  • 94
  • 114
9

If you're using mock to patch sys.exit, you may be patching it incorrectly.

This small test works fine for me:

import sys
from mock import patch

def myfunction():
    sys.exit(1)

def test_myfunction():
    with patch('foo.sys.exit') as exit_mock:
        myfunction()
        assert exit_mock.called

invoked with:

nosetests foo.py

outputs:

.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Adam Wagner
  • 15,469
  • 7
  • 52
  • 66
  • 4
    Problem with this is that whilst the mock will be called, it won't stop execution, any instructions after the exit will be called. I.E. if you are exiting because of an error state, the test would carry on to attempt to run potentially broken code. – Graeme Jun 29 '20 at 21:15
7

This is an example in the unittest framework.

with self.assertRaises(SystemExit) as cm:
    my_function_that_uses_sys_exit()
self.assertEqual(cm.exception.code, expected_return_code)
Tarrasch
  • 10,199
  • 6
  • 41
  • 57
7
import sys
sys.exit = lambda *x: None

Keep in mind that programs may reasonably expect not to continue after sys.exit(), so patching it out might not actually help...

kindall
  • 178,883
  • 35
  • 278
  • 309
0

From this article on medium:

def test_exit(mymodule):
    with pytest.raises(SystemExit) as pytest_wrapped_e:
            mymodule.will_exit_somewhere_down_the_stack()
    assert pytest_wrapped_e.type == SystemExit
    assert pytest_wrapped_e.value.code == 42
aless80
  • 3,122
  • 3
  • 34
  • 53