Consider a method which might throw an exception with some descriptive text:
if ($someCondition) {
throw new \Whatever\Exception('dilithium exhausted');
}
And elsewhere in the method is another block that might throw the same exception, but with different text:
if ($anotherCondition) {
throw new \Whatever\Exception('differentialator exploded');
}
While writing unit tests for this class, you create failure cases so that you can verify that these two exceptions get thrown properly. In these failure cases, do you prefer to:
A) Use @exceptionExpected in the test method's docblock to trap the generic \Whatever\Exception class and subsequently ignore the getMessage() text, assuming you got the right one? (Seems like a bad idea.)
or:
B) Use try/catch and then assert that the caught exception's getMessage() text equals the exact descriptive string you're expecting? (More resilient but it means changing your tests whenever you change your error wording.)
or:
C) Create a separate exception for each error case (e.g., \Whatever\DilithiumException and \Whatever\DifferentialatorException) and then use @exceptionExpected for each one.
I'm currently using B but tending toward C. I'm curious what others are doing in this same scenario. Do you have any guidelines that help you determine, "At what point does an error deserve its own exception class versus a more generic shared one?"