Unit testing 单元测试中的依赖关系

Unit testing 单元测试中的依赖关系,unit-testing,testing,dependencies,Unit Testing,Testing,Dependencies,我不熟悉单元测试,但我倾向于认为我相信编写精美的代码和设计合理的体系结构 我的问题是。单元测试不是过于关注对象之间的依赖关系吗?当您的单元测试失败时,您会怎么做?因为您的方法之前调用的依赖项不再被调用(设计决策),或者您的方法调用另一个方法或依赖项(再次是设计决策)。您会重新设计测试吗?如果是这样的话,那么单元测试对于减少组件之间的耦合和提高组件之间的内聚性几乎没有帮助 也许我的观点太宽泛了,但一般来说,人们如何在恰当的单元测试中处理依赖关系呢。我想最好的方法是完全没有依赖关系,每个方法都依赖于

我不熟悉单元测试,但我倾向于认为我相信编写精美的代码和设计合理的体系结构

我的问题是。单元测试不是过于关注对象之间的依赖关系吗?当您的单元测试失败时,您会怎么做?因为您的方法之前调用的依赖项不再被调用(设计决策),或者您的方法调用另一个方法或依赖项(再次是设计决策)。您会重新设计测试吗?如果是这样的话,那么单元测试对于减少组件之间的耦合和提高组件之间的内聚性几乎没有帮助


也许我的观点太宽泛了,但一般来说,人们如何在恰当的单元测试中处理依赖关系呢。我想最好的方法是完全没有依赖关系,每个方法都依赖于给定的参数,但实际上情况并非如此。此外,对每一个可能的调用伪造每个依赖方法也是有点主观和浪费时间的,因为在将来的时间点,被测试的类可能不再需要依赖性。

< P>如果您在讨论单元测试,则没有依赖关系,导致单元测试只测试一个类(java、C++、露比、python)。. 你所说的听起来更像是集成测试,这是不同的。此外,如果您有太多的依赖关系,那么您的耦合程度很高,这不是很好,但当然并非总是可以避免的。

我建议您考虑测试驱动开发(TDD),因为我相信这种技术将帮助您解决设计问题。通过在编写生产代码之前编写单元测试,您需要考虑如何使生产代码可测试。这比后面的测试方法更好,在这种方法中,您首先编写生产代码,然后尝试围绕它们进行测试

要处理依赖关系,请考虑是什么依赖关系给您带来了问题

外部依赖关系

如果您的测试使用外部资源,例如文件,那么您正在编写集成测试,而不是单元测试。我已经编写了许多使用外部文件的测试,我只是在测试项目中创建了该文件的副本。此文件副本将包含测试所需的虚拟数据

如果您的测试需要数据库,那么再次编写集成测试。就我个人而言,我在电脑上创建了数据库的本地副本,并对其运行测试

对象依赖关系

如果您担心代码依赖性(例如,如果私有方法的签名被更改,您的测试将失败),那么您在错误的抽象级别进行测试。我的意思是确保您的测试调用的是公共API,而不是私有API。要巩固这一点,请对对象使用
接口
,以确保实现它的对象具有预期的契约

我还建议您尝试使用模拟框架,例如,或


模拟框架将帮助您消除对数据库的依赖,例如,为您的测试提供一个数据库。我个人使用TypeMock,它不便宜,但它是迄今为止最强大的工具。

单元测试应该测试行为,而不是实现。这样,在更改实现或重构代码时,可以依赖单元测试。删除依赖项(例如通过内联类)不会破坏测试


测试实现会导致脆弱的测试,这会在重构时造成阻碍

是的,来看看99%的代码都写在那里了。依赖关系无处不在,您很难编写一个不在另一个对象上调用方法的方法。一个明显的例子是JavaYes中控制器和DAO对象之间的耦合,当然了,但是我们讨论的是集成测试,而不是单元测试。在本例中,您提出的问题是:控制器是否可以进行单元测试?我会说不,因为控制器不是唯一的…所以你必须做一个集成测试。但是,这是否意味着你将在一年后依赖同一个接口:)这里的关键点是,当生产代码更改时,它有可能会破坏你的测试。你无法逃避。没有办法100%保护您的测试代码不受破坏性更改的影响。设计对象的方式将决定测试的中断程度。我知道这很烦人,我去过那里,但没有什么灵丹妙药。这也是一直困扰我的。好吧,如果测试失败,我如何测试我的方法是否能为一组特定的参数返回一些结果,因为我的方法调用根本没有声明依赖:)类有责任(最好是一个)以及合作。如果您更改了协作(即设计),而不是责任,那么测试不应该中断。