pythonexceptionsqlalchemypython-unittestassertraises

Cant understand results while using assertRaises in unit testing on a sqlalchemy code


I am trying to unit test my sqlalchemy code.

    def add_user(*user_details):
         try:
             u = User(*user_details)
             session.add(u)
             session.commit()
         except:
             session.rollback()

Now in my unit test:

    def testDuplicate(self):
         add_user(user_detail1,user_detail2)
         self.assertRaises(IntegrityError, add_user(user_detail1,user_detail2))

This test should succeed if add_user function call raises an Integrity error and fail if there is no exception. But the problem is test succeeds in both cases.

Why is this happening? Is there something wrong in my code? or assertRaises works differently than what I am expecting out from it?

Atfirst I thought this is happening because I have put except in my try clause and exception is dealt there only and assertRaises does not get exception. But if this would have been the case then assertRaises should have failed on not receiving the exception.

If there is something wrong in way of writing my unit test then do tell me because I am still learning to incorporate unit testing in my coding habits.


Solution

  • You are using assertRaises incorrectly, instead you should write:

    self.assertRaises(IntegrityError, add_user, user_detail1, user_detail2)
    

    You give the function and the arguments separately to assertRaises so it can control when the function is called (e.g. in a try/except block in assertRaises).

    The other problem is that the function under test is swallowing the error. Try

    def add_user(*user_details):
             try:
                 u = User(*user_details)
                 session.add(u)
                 session.commit()
             except:
                 session.rollback()
                 raise
    

    which will re-raise the exception (but allowing the transaction to be rolled back).