Unit testing 如何将其分解为单元测试?

Unit testing 如何将其分解为单元测试?,unit-testing,refactoring,Unit Testing,Refactoring,我有一个对对象调用的方法来执行一些业务逻辑并将其添加到数据库中 该对象是一个事务,业务逻辑的一部分要求在数据库中搜索帐户上的相关帐户和历史记录项 然后需要进行一系列比较和操作,从帐户中带回信息并将其应用于事务,然后再将事务传递给其他人并写入数据库 目前我能想到的唯一测试方法是在测试中创建一个帐户和相关的历史信息,然后为每个不同的场景构建一个事务,并捕获写入DB的事务信息和传递的信息,然而,这让人感觉它在一次测试中的测试方式太多了。每个场景都将在一个单独的单元测试中执行,测试结构将重构为单独的方法

我有一个对对象调用的方法来执行一些业务逻辑并将其添加到数据库中

该对象是一个事务,业务逻辑的一部分要求在数据库中搜索帐户上的相关帐户和历史记录项

然后需要进行一系列比较和操作,从帐户中带回信息并将其应用于事务,然后再将事务传递给其他人并写入数据库

目前我能想到的唯一测试方法是在测试中创建一个帐户和相关的历史信息,然后为每个不同的场景构建一个事务,并捕获写入DB的事务信息和传递的信息,然而,这让人感觉它在一次测试中的测试方式太多了。每个场景都将在一个单独的单元测试中执行,测试结构将重构为单独的方法,但是测试所针对的实际代码段长度超过500行

我想这个问题更多的是关于重构而不是单元测试,但在这种情况下,它们是齐头并进的

如果有人有什么建议(好的或坏的),我很乐意听

编辑:

伪代码:

Find account for transaction 
Do validation on transaction codes and values 
Update transaction with info from account 
Get related history from account Handle different transaction codes and values (6 different combinations, each with different logic) 
Update the transaction again with new account info (resulting from business logic) 
Send transaction to clients

这取决于您想测试什么。是否要测试数据库事务?您想测试业务事务还是其他什么?试着对你不想测试的东西使用模型。有了实体模型,您可以专注于某些测试目标。

如果您在这个问题上有一些伪代码,我将不胜感激,但只要遵循它,我会:

  • 为直接访问数据库的数据访问对象创建接口-通过这种方式,您可以传入一个仅假装(例如,模拟)访问数据库的对象。然后,该对象将返回与数据库将返回的结果一致的结果,而不实际执行任何DB调用。您的对象还可以模拟场景,例如将数据回滚到其原始状态
  • 将每个“场景”提取到单个方法中,每个方法都是一个单元的本质。如果您的方法有500行长,那么其中必须有可以提取的连续块。如果合适的话,为每一个写一个单元测试
  • 如果您的单元测试测试太多,这可能意味着您的方法做得太多了-您可以通过识别您正在测试的不同内容,然后将它们放在自己的方法中来提取方法。冲洗并重复,直到每种方法只需要一次测试
  • 事务“传递给其他人”听起来像是一种代码气味-事务本身应该只是一个连续的单元。如果你需要不同的用户来完成你的交易,你做的太多了;而是通过标记等方式,而不是通过DB事务来跟踪数据在DB上的状态

是的,您可以重写当前代码,以便根据需要对其进行单元测试 遵守所有准则和最佳做法

然而,这可能很昂贵,您应该估算成本并进行比较 根据收入

这样做的好处是,您可能会发现代码有问题,而且,如果做得对,重构的结果是复杂性的降低

这两个因素都可能在将来节省一些时间

成本是您在重构代码和, 编写测试用例以及将来可能需要花费的额外时间 维护测试用例和模拟代码——这可能是巨大的成本

你正在将已知成本与未来风险进行比较,我相信很多聪明人都知道如何做到这一点,但很明显,你实际上可以花无限的时间进行重构和模拟,而不会将失败的风险降至零(或者即使代码和问题很复杂,而你在重构时把事情搞砸了),所以你需要在这里找到一个平衡点

在这种情况下,由于代码很旧,所以可以“草率”或“务实”,进行黑盒测试或自顶向下测试,只测试接口(或抽象),而不必费心模拟数据库。是的,你可以说这不是一个单元测试,而是一个系统测试或功能测试实践

…但是,它可能会让你的钱或你的雇主/客户的钱物有所值,或者让你有更多的时间与你的另一半在一起(或者至少有更多的时间观看探索频道)


如果您有旧代码,请允许黑盒测试,允许测试之间的依赖关系,并编译一系列测试,以设置测试数据并对其进行操作,并且至少在未进行100%测试的情况下自动对其进行测试。

从现有遗留代码中分离单元可能非常棘手且耗时。查看各种经过尝试和测试的技术,使事情更易于管理

关于发送什么、保存什么以及如何更新帐户,有很多复杂的逻辑。我需要能够测试所有这些,因为任何更改都可能导致混乱。谢谢Jon,我将尝试添加一些伪代码(不会泄露太多IP…)此外,在这种情况下,事务是金融事务,而不是与原子数据库操作相关的事务。如果人们要否决某个条目,请在随后评论原因,因此,作者有机会改进这些工作。