Home > database >  Implementing assertRaises unittest for class/class method
Implementing assertRaises unittest for class/class method

Time:11-27

I have written a class in Python that is intialized with a few arguments.

Iam trying to write a test that check if all the arguments are int, otherwise throw TypeError.

Here is my attempt :

import unittest
from footer import Footer

class TestFooter(unittest.TestCase):

    def test_validInput(self):
        footer = Footer(4,5,1,0)
        self.assertTrue(footer.validInput())
        #attempt 1:
        footer1 = Footer("four","five",1,0)
        self.assertRaises(TypeError, footer1.validInput())
        #attempt 2:
        with self.assertRaises(TypeError):
            Footer("four",5,1,0)

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

However, this will not work. I don't understand why.

Here is the class, I'am writting the test for:

class Footer:
    def __init__(self, current_page: int, total_pages: int, boundaries: int, around: int):
        self.current_page = current_page
        self.total_pages = total_pages
        self.boundaries = boundaries
        self.around = around
        try:
            if (self.validInput()):
                footer = self.createFooter()
                self.addEllipsis(footer)
        except Exception as e:
            print(f"\nError while initializing Footer Class ({e.__class__}).\n Please fix the following: ", e)
        
    def validInput(self) -> bool:
        if (type(self.total_pages) != int or type(self.boundaries) != int or type(self.around) != int or type(self.current_page) != int ):
            raise TypeError("Invalid input. All the arguments must be of type int.")
        if (self.total_pages < 0 or self.boundaries < 0 or self.around < 0 or self.current_page < 0):
            raise ValueError("Invalid values. Please do not provide negative values.")
        if (self.current_page > self.total_pages):
            raise ValueError("Current page must be within the total number of pages")
        return True

    def createFooter(self) -> list:
        footer = []
        for page in range(1, self.total_pages   1):
            if (page <= self.boundaries):
                footer.append(page)
            elif (page > self.total_pages-self.boundaries):
                footer.append(page)
            elif (page == self.current_page):
                footer.append(page)
            elif ((page > self.current_page and page <= (self.current_page   self.around)) or (page < self.current_page and page >= self.current_page - self.around)):
                footer.append(page)
        return footer

    def addEllipsis(self, footer: list) -> None:
        final_footer = [] 
        i = 0
        for page in footer:
            try :
                final_footer.append(page)
                if(footer[i   1] - footer[i] > 1):
                    final_footer.append("...")
            except IndexError:
                break
            i  = 1
        print("\n", ' '.join(str(page) for page in final_footer))


Here is the output for the test :

enter image description here

CodePudding user response:

This is the wrong way to use assertRaises:

import unittest


def this_func_raises():
    raise ValueError


class TestClass(unittest.TestCase):
    def test1(self):
        self.assertRaises(ValueError, this_func_raises())

Note that the ValueError will be raised if you include the (), since that would execute this_func_raises and the exception will not be caught.

And this is the right way:

import unittest


def this_func_raises():
    raise ValueError


class TestClass(unittest.TestCase):
    def test1(self):
        self.assertRaises(ValueError, this_func_raises)

Note that there are several other problems in your code. For example this:

with self.assertRaises(TypeError):
    Footer("four", 5, 1, 0)

Should be like so:

with self.assertRaises(TypeError):
    Footer("four", 5, 1, 0).validInput()

Lastly, you need to replace self.createFooter() with a pass until you implement it, or you ll get another error.


This is how your code should look like in order to pass the tests:

class Footer:
    def __init__(self, current_page: int, total_pages: int, boundaries: int, around: int):
        self.current_page = current_page
        self.total_pages = total_pages
        self.boundaries = boundaries
        self.around = around
        try:
            if (self.validInput()):
                # self.createFooter()
                pass
        except Exception as e:
            print(f"\nError while initializing Footer Class ({e.__class__}).\n Please fix the following: ", e)

    def validInput(self) -> bool:
        if (type(self.total_pages) != int or type(self.boundaries) != int or type(self.around) != int or type(
                self.current_page) != int):
            raise TypeError("Invalid input. All the arguments must be of type int.")
        if (self.total_pages < 0 or self.boundaries < 0 or self.around < 0 or self.current_page < 0):
            raise ValueError("Invalid values. Please do not provide negative values.")
        if (self.current_page > self.total_pages):
            raise ValueError("Current page must be within the total number of pages")
        return True

test file:

import unittest


class TestFooter(unittest.TestCase):

    def test_validInput(self):
        footer = Footer(4, 5, 1, 0)
        self.assertTrue(footer.validInput())
        # attempt 1:
        footer1 = Footer("four", "five", 1, 0)
        self.assertRaises(TypeError, footer1.validInput)
        # attempt 2:
        with self.assertRaises(TypeError):
            Footer("four", 5, 1, 0).validInput()

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