Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test if the right exception is raised and caught using unit testing?

I would like to test if a proper exception is raised and caught using unittest.

Below is my sample code:

def foo():
    try:
        raise Exception(ValueError)
    except ValueError:
        print "raised"

Here is what I would like to do:

self.assertRaises(ValueError, foo)

Since I caught the exception I'm not able to assertRaise the exception. Am I missing something or is there any other way?

My full code:

#!/usr/bin/python
import unittest
def foo():
    try:
        raise ValueError
    except ValueError, e:
        print "caught"
class tester(unittest.TestCase):
    def test1(self):
        with self.assertRaises(ValueError):
            foo()
    def test2(self):
        self.assertRaises(ValueError, foo)
if __name__ == '__main__':
    unittest.main()
like image 569
Madhan Gokul Avatar asked Aug 10 '15 11:08

Madhan Gokul


2 Answers

No, you cannot test things that only have effects inside the function from outside of it.

What you can do is split the code that raises the exception into its own function, and then test that to check that the exception is raised (with assertRaises). The original function can call that one, and if your normal tests on that work then apparently it catches the exception.

However, whether that is a good idea depends on what your function does. Why does it matter that the function raises an exception at some point and then catches it? Maybe one day you'll switch to some other way to do the same thing, with the same results. Shouldn't your tests keep working then?

If the exception thing is just an implementation detail, you probably shouldn't test it at all.

like image 124
RemcoGerlich Avatar answered Nov 09 '22 13:11

RemcoGerlich


You can capture stdout and test for a string match. Pytest offer a fixture for that.

#!/usr/bin/python
import unittest

def foo():
    try:
        raise ValueError
    except ValueError, e:
        print "caught"

def test_foo(capfd):
    foo()
    out, err = capfd.readouterr()
    assert out == "caught\n"

py.test test.py

============================= test session starts ==============================
platform linux2 -- Python 2.7.9 -- py-1.4.28 -- pytest-2.7.1
rootdir: /tmp, inifile: 
collected 1 items 

test.py .

=========================== 1 passed in 0.01 seconds ===========================
like image 41
Cyrbil Avatar answered Nov 09 '22 13:11

Cyrbil