Puck
Puck

Reputation: 2120

Set unit test for raised exception in property setter

I am using property setter and raising errors if inputs are not the expected type. I am also unit testing all functions and want to test that the exception is actually raised when using the setter.

I try to get a callable to give to unittest.TestCase.assertRaises. Here is an example:

import unittest

class A:
    def __init__(self, num):
        self.var = num

    @property
    def var(self):
        return self._var

    @var.setter
    def var(self, new):
        if not isinstance(new, int):
            raise TypeError
        self._var = new

class TestA(unittest.TestCase):
    def test_a_setter(self):
        a = A(5)
        self.assertRaises(TypeError, a.var = 'a') #<--- a not working try

if __name__ == '__main__':
    unittest.main()

Is there a way to get the setter callable ? Else, I'll just use try ... except block, but this doesn't look like a clean solution.

Another idea I got is to use setattr but this doesn't work with property.

Upvotes: 2

Views: 860

Answers (1)

MrBean Bremen
MrBean Bremen

Reputation: 16855

Using the context manager variant for assertRaises should work:

class TestA(unittest.TestCase):
    def test_a_setter(self):
        a = A(5)
        with self.assertRaises(TypeError):
            a.var = 'a'

This also makes the test better readable in most cases, so I generally prefer this style.

And just for completeness, here is the (ugly) answer to your actual question:

class TestA(unittest.TestCase):
    def test_a_setter(self):
        a = A(5)
        self.assertRaises(TypeError, A.var.__set__, a, 'a')
        # alternative using lambda:
        self.assertRaises(TypeError, lambda: A.var.__set__(a, 'a'))

Upvotes: 4

Related Questions