我正在测试一个方法,如果传递给该方法的参数超过某个业务规则限制,该方法几乎会立即抛出异常。
我测试的类有依赖项,所以我嘲笑它们。然而,由于异常几乎会立即抛出,我是否可以(正确吗)只嘲笑我需要的东西?还是我需要指定整个测试?
我希望抛出异常,所以我需要模拟所有对象并设置返回值等吗?
在这些情况下,什么是正确的?在同一个测试中同时进行验证和断言是错误的吗?
如果您能有一些代码示例,那就太好了。但是,正如我理解你的问题一样,你是在单元测试一个方法,它会在检查某种业务规则后立即抛出异常。您还将依赖项注入到这个类中(SUT-测试中的系统)。这些依赖关系在单元测试中被嘲笑/存根,但由于异常会立即抛出,您不确定嘲笑所有内容是否是个好主意。
通常,对于任何单元测试,您都希望绝对确保您的单元测试只包含它需要的内容,而不包含其他内容。如果你在单元测试中嘲笑存根,而它们在SUT中的测试执行过程中没有被使用,那么
a。您的测试可能更难维护,也更难阅读,因为要弄清楚测试实际使用了什么以及测试实际在做什么可能并不容易。
b。你的测试可能会因为错误的原因而失败。例如,你的SUT完全按照你期望的方式工作,但由于不需要的依赖性被嘲笑,任何重构和测试都会因为错误的原因而失败。这也被称为假阳性测试。
您应该尝试实现的是编写一个单独的单元测试来验证异常场景。这个测试只会注入依赖项,使您的规则违反,这样您就可以测试异常场景。所有其他测试都会相应地注入依赖项,以使这些测试尽可能满足要求。
我想这个问题没有最终的答案,但正如我在Spocks答案的评论中所说,无论特定的测试是否会使用它,我所做的总是提供被测试类所需要的所有依赖项。我这么做的原因如下:
基本上,实现可能会更改,但如果满足预期的行为,我的测试应该仍然通过。请注意,不使用依赖项可能是一种明确的预期行为。在这种情况下,我认为它可以省略。
至少在使用TDD(应该首先编写测试)时,当您编写测试时,您不知道什么时候会抛出异常。除非您没有明确的行为要求,否则从测试的角度来看,这应该是完全透明的。