测试第三方库的智能包装

时间:2011-05-07 21:51:30

标签: unit-testing testing tdd integration integration-testing

假设您需要使用不必要的复杂,难以模拟(可能它具有没有虚拟接口的具体类),以及与某些外部资源(如套接字或数据库)集成的不可靠的第三方库。您决定创建“包装器”接口/类以大大简化此库的使用,并允许使用包装器的开发人员继续编写可测试代码。包装器的界面看起来与原始界面完全不同。

我有一些关于如何测试这个包装器的问题。

  1. 是否应该在没有外部资源的情况下测试包装器,方法是在可以模拟的坏库上开发方法方法层?

  2. 使用第三方库(使用外部资源)测试包装类时,这是单元测试还是集成测试?如果外部资源可以在自动化测试期间嵌入到内存中,它还是一个集成测试吗?

  3. 我们在什么时候放弃嘲弄和抄袭并说我们有一个单位。根据维基百科“一个单元是应用程序中最小的可测试部分”。但我发现这很难衡量。如果速度是决定我们是否正在测试一个单元的一个因素,那么如何判断测试被称为单元测试的速度有多慢?

3 个答案:

答案 0 :(得分:9)

TDD并没有说一切都必须经过单元测试。 TDD说你应该先写一个测试,但它不一定是单元测试。

  1. 从集成测试开始 - 它将根据与真实组件通信的包装器测试您的逻辑。这里没有嘲笑。它是集成测试,因为它测试应用程序的多个层,而实际组件仍然使用套接字或数据库访问。
  2. 集成测试将失败,因为您没有逻辑
  3. 使用模拟包装器编写单元测试来测试逻辑
  4. 单元测试将失败,因为您没有逻辑
  5. 编写逻辑以满足单元测试(4。)
  6. 重复3.-5。获得满足集成测试所需的所有逻辑(1.)
  7. 使用下一个集成测试重复整个过程
  8. 无需为包装器编写单元测试。主包装器的功能是包装组件。如果您为包装器编写单元测试,您将测试它在组件上调用方法,但在这种情况下,您回到开头 - 如何模拟组件?如果您只是为包装器调用组件而编写集成测试,那么您正在重新测试组件(好的,这有时很方便,但在正常情况下您不会这样做)。

    我建议阅读Steve Freeman和Nat Pryce的Growing Object-Oriented Software guided by tests

答案 1 :(得分:6)

我认为这个问题围绕着这个陈述:

  

包装器的界面看起来与原始界面

完全不同

这可能表明包装器和原始接口之间的转换涉及大量逻辑。这听起来很像anti-corruption layer,如果这个逻辑很复杂,那就应该进行测试。

最好的方法仍然是从原始API中提取1:1接口。但是,这不是您向应用程序其余部分公开的接口。您向应用程序其余部分公开的接口可以是提取的接口上的Facade。从某种意义上说,你可以说提取的接口是反腐败层的实现细节,而不是暴露给应用程序其余部分的东西。

这使您可以对Facade界面和提取的界面之间的转换进行单元测试,同时仍然保持原始的,难以测试的组件不在测试范围内。

提取的界面和原始组件之间的转换仍然是什么。但是,如果将该接口提取为原始组件的1:1映射,则实现应包含纯委托。换句话说,实现的圈复杂度为1,因此不需要进行单元测试Humble Object

您可能仍希望在已完成的系统上进行一些集成或系统测试,但这些测试可能会起到冒烟测试的作用,因为您应该已经从单元测试中获得足够的覆盖率。

答案 2 :(得分:2)

广告1)不是简短的回答。包装器除了包装外不应该做任何其他事情。因此,集成测试是唯一有意义的事情。

广告2)是的。

Ad 3)当你的目标只针对一件事时停止,并让外部物体 - 注入和模拟 - 做其他一切(SRP)