5

I have read this Q&A, and already try to catch exception on my code that raise an IntegrityError exception, this way :

self.assertRaises(IntegrityError, db.session.commit())

But somehow my unit test still failed and stop with IntegrityError exception. I expect it to say OK as I already expect to have exception in my unit test. This was cause by code that tries to insert row having the same unique field values.

Any idea?

Community
  • 1
  • 1
swdev
  • 4,797
  • 8
  • 59
  • 101

1 Answers1

6

One of these will to the trick:

# ... only if version >= 2.7
with self.assertRaises(IntegrityError):
    db.session.commit()

Or:

self.assertRaises(IntegrityError, db.session.commit)

The difference between your example and the correct way is:

# Your example: You call db.session.commit(), this will raise an exception before
# assertRaises is called
self.assertRaises(IntegrityError, db.session.commit())

# Correct way: Pass what should be called to assertRaises, 
# let assertRaises invoke it and check for exception
self.assertRaises(IntegrityError, db.session.commit)

I prefer to use assertRaises as a context manager (using with).

codeape
  • 94,365
  • 23
  • 147
  • 176
  • Phew.. this solved and brighten my day! Thanks! :) Right, I was thinking earlier that the argument accept function name, not call of the function. But, somehow I miss that when I do the actual code. But, why do you prefer to use a context manager? Isn't with this single line the result will be the same? – swdev Oct 10 '13 at 07:39
  • Added comment,I just use context manager as you pointed out, and I think the other benefit is that we can expand/refine our code much more in that indented block. I am still new in python, so that's what I am getting :) – swdev Oct 10 '13 at 07:41
  • 1
    I agree. I think using assertRaises as a context manager makes the test code clearer. – codeape Oct 10 '13 at 09:28