How to properly use unit-testing's assertRaises with NoneType objects
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
assertRaises is for testing exception behavior, not for checking whether a function returned None. The confusion usually starts when a function receives None as input and the test writer has not yet decided what the function is supposed to do. The correct test depends on the contract: reject None with an exception, or accept it and return None.
Use assertRaises When the Contract Is Exception-Based
If None is invalid input, the function should raise a specific exception and the test should assert that exact behavior.
This is correct because the function contract says None is not allowed.
Use assertIsNone When None Is a Valid Outcome
If the function is supposed to return None in some cases, assertRaises is simply the wrong tool.
That is a return-value assertion, not an exception assertion.
Prefer the Context Manager Form
unittest supports both callable-style and context-manager-style assertRaises. The context-manager form is usually clearer because the exact failing line is obvious.
This style also makes it easier to add more setup around the failing call later.
Check the Error Message Only When It Matters
If the type alone is not enough, use assertRaisesRegex.
Use this when the message is part of the function’s public behavior, not for every tiny wording detail.
Test the Contract, Not a Lucky Failure
A weak test says “something failed.” A useful test says exactly what should happen:
- '
Noneinput raisesTypeError' - invalid data raises
ValueError - missing lookup result returns
None
That is why the design question comes first. If you do not know whether the function should raise or return None, settle that before writing the assertion.
Parameterize Invalid Inputs When Helpful
If several invalid values should fail, use subTest to keep the test compact but explicit.
This keeps multiple edge cases readable without duplicating boilerplate.
Callable Style Still Exists
assertRaises also has an older callable form such as self.assertRaises(TypeError, func, None). It works, but the context-manager form is usually easier to read, especially once setup code or message assertions become part of the test.
That readability benefit matters because test code is documentation too, not just a pass-fail mechanism.
Common Pitfalls
- Using
assertRaisesfor functions that should simply returnNone. - Catching broad
Exceptioninstead of a specific exception type. - Putting too much code inside the
assertRaisesblock and testing the wrong line. - Writing the test before deciding the function’s intended contract.
Summary
- Use
assertRaisesonly when the expected behavior is an exception. - Use
assertIsNonewhen the expected result isNone. - Prefer the context-manager form for readability.
- Assert specific exception types rather than broad failure categories.
- Decide the function contract first, then choose the matching assertion.

