【问题标题】:Is it ok to modify the source to make unit tests work?可以修改源代码以使单元测试工作吗?
【发布时间】:2015-04-12 22:45:54
【问题描述】:

我有一个我想进行单元测试的方法,它检查三张卡之间的匹配。因为卡片是随机生成的,所以无法设置三张我知道会匹配或不会匹配的卡。我需要这样做来对我的isMatch() 方法进行单元测试。

是否可以更改我的 Card 类以添加一种方法来显式设置其值以便我可以对其进行单元测试?一般来说,对源代码进行少量添加以使单元测试成为可能是可以接受的,还是有更好(或更正确)的方法来做到这一点?

【问题讨论】:

  • 你应该将随机性的来源,Random 实例注入你的类。在您的测试中,您可以创建一个已知的随机序列并测试逻辑。代码应该写成可测试的。如果它不可测试,是的,应该改变它。
  • 你没有使用种子来实现随机性吗?你写的地方没有小日志文件,所以你可以重新创建?
  • @BoristheSpider,你能详细说明注入Random 实例吗?我不清楚你的意思。
  • 阅读Inversion of Control 模式。
  • +1 表示Boris the Spider's 评论,但我认为Dependency Injection 这个词更容易理解和理解。

标签: java unit-testing junit4


【解决方案1】:

不知道你的设置是什么,但为什么不让卡片生成器成为你的类的可插拔组件和fake 保证返回三张匹配卡片的类?

然后您可以fake 一个保证返回三张不匹配的卡片的类。

【讨论】:

  • 我考虑过使用卡片生成器,或者更具体地说是 CardFactory 或 CardBuilder。问题是 Card 类不需要很多自上而下的创建。所以我写了卡片类来管理它自己的随机化。当其他类请求一张卡片时,他们只需要调用默认构造函数,就可以期待一张随机卡片。我相信自下而上的设计会更好,但它确实需要添加更多代码来显式创建卡片,以便可以测试 isMatch 方法。
  • 做你正在做的事情当然没问题,但是现在将随机化添加到 Card 类中,你永远不会有不同的策略来生成卡片。这是一个不错的决定,但它确实会带来一些后果,正如您很可能已经注意到的那样。就像无法编写清晰简洁的单元测试一样。 Uncle Bob 会说你的 Card 类正在做两件事,一般来说,一个类应该只做一件事。
  • 改变 Card 接口以获取 Configuration 对象是微不足道的。毕竟,我不是在写 API,所以“永远不会有不同的策略来生成卡片”这句话并不是一成不变的。你的建议很好,我最初写的时候也考虑过。问题是没有自配置,Card类只是一个数据结构,保存着卡片的属性;这也不是好的设计。正如您所提到的,您不知道整个设置,但我认为您的回答最有用。
【解决方案2】:

没有。您不应修改单元测试的代码并将其修改回来,因此“代码运行”。对于所描述的问题,您有@Before。围绕这个设计你的课程。构建三张确定性卡片并进行比较。使用此注释,您可以测试代码的功能,而无需“修改代码以进行单元测试”。

【讨论】:

  • 我正在使用@before。这不是问题,问题是当前界面没有确定的方法来创建卡片。这不是代码运行的问题。它在两种情况下都运行,在原始情况下以及如果我添加一种确定性地制作卡片的方法。我只是问是否“正确”向源添加方法以便可以完成测试。
  • @Hal50000 没问题。
猜你喜欢
  • 2011-01-21
  • 2021-05-20
  • 1970-01-01
  • 2019-09-26
  • 2018-02-20
  • 2013-12-15
  • 2019-08-25
  • 2018-04-30
  • 1970-01-01
相关资源
最近更新 更多