Listen to this post
Exceptions in software represent a mechanism for raising an alarm when something goes wrong. They are used when there is a potential problem that cannot be detected by the compiler, linker, or other automated aspect of the development process, and thus may potentially make it into the released product.
When an exception is declared in the code, it is basically a way of saying, “We hope this never happens, but if it does at least we’ll be made aware of it.” Getting the exception is bad news, but the problem that caused it is made visible so we can deal with it. Not getting the exception is good news. Everything is fine.
In TDD, however, this is logically reversed.
If the decision is made that an exception should be thrown under a given situation and if, in a test of that situation, it is indeed thrown then this is good news. The system is behaving as intended. It is when the exception should have been thrown but was not that we have a problem to deal with. Not getting the exception is the bad news.
Throwing exceptions is a behavior of the system. Like all behavior it must be part of the specification and in TDD, this means it must be driven by a test that initially fails. Exceptions, in other words, are no exception!