考虑一个可能抛出包含一些描述性文本的异常的方法:
if ($someCondition) {
throw new \Whatever\Exception('dilithium exhausted');
}该方法中的其他地方是另一个可能抛出相同异常的块,但具有不同的文本:
if ($anotherCondition) {
throw new \Whatever\Exception('differentialator exploded');
}在为该类编写单元测试时,您将创建失败案例,以便可以验证这两个异常是否被正确抛出。在这些失败的情况下,您是否倾向于:
A)在测试方法的文档块中使用@exceptionExpected来捕获泛型\ assuming \Exception类,然后忽略getMessage()文本,假设您得到了正确的文本?(看起来不是个好主意。)
或者:
B)使用try/catch,然后断言捕获的异常的getMessage()文本与您期望的描述性字符串完全相同?(更具弹性,但这意味着每当您更改错误措辞时,都要更改测试。)
或者:
C)为每个错误案例创建一个单独的异常(例如,\ and \DilithiumException和\ and \DifferentialatorException),然后为每个错误案例使用@exceptionExpected。
我目前使用的是B,但倾向于使用C。我很好奇在这个相同的场景中,其他人在做什么。您是否有任何指导原则可以帮助您确定:“在什么情况下,错误应该拥有自己的异常类,而不是更通用的共享异常类?”
发布于 2010-12-21 04:45:43
以上都是。
A很棒,我尽可能多地使用它,因为它最简单。还有另一种A不起作用的情况:
/**
* @exceptionExpected FooException
*/
test() {
// code that could throw FooException
...
// purpose of the test that throws of FooException
}在这种情况下,测试可以在本应失败的时候通过,因为它甚至没有达到我正在测试的内容。处理这个问题的一个好方法是使用$ this ->setExpectedException()
当您可能实际使用异常中的信息时,B非常有用。与使用异常消息的文本相比,我更喜欢使用代码。我有一个表单验证异常,它将数据中遇到的所有问题打包到一个异常中。通过扩展异常类,可以很容易地将大量信息从内部错误状态传输到外部处理代码。
C实现了与B相同的功能,但允许通过依赖更多的类来简化代码。这两者之间的区别是微妙的,我倾向于依靠设计美学来做出决定。
TL;DR:使用异常代码而不是消息,并针对用例而不是单元测试进行设计。
发布于 2011-02-05 17:42:17
当您需要这种级别的细节时,PHPUnit还提供了@expectedExceptionCode和@expectedExceptionMessage。警告:后者需要前者。
顺便说一句,我也倾向于A。如果我需要在异常中表达更多的含义,我更喜欢创建一个新的异常类。我发现消息太不稳定,不值得在大多数应用程序中进行测试。
https://stackoverflow.com/questions/4493430
复制相似问题