【问题标题】:During TDD how to test following scenarios [closed]在TDD期间如何测试以下场景[关闭]
【发布时间】:2017-11-07 06:02:31
【问题描述】:

尝试采用 TDD 进行开发,但在某些情况下我没有最佳选择,如何编写代码和测试它们。

以下是代码场景:

  1. 有一个公共方法说 Initialize(),它只初始化类的私有成员。如何测试此方法是否工作正常。

  2. 有一个私有方法说 DoSomething() 并被同一类 Caller1() 和 Caller2() 的 2 个公共方法调用。在为这两种方法编写单元测试时,我不能模拟 DoSomething() 因为它是私有的,但是这个方法代码将被测试两次。 在这种情况下如何编写代码/测试?

  3. 有一个公共方法 DoSomething() 被另一个公共方法 Caller() 调用。 DoSomething() 初始化一个私有成员,然后在 Caller() 中使用该成员。我可以在测试 Caller() 时模拟 DoSomething() 但无法在私有成员中设置数据。 在这种情况下如何编写代码/测试?

如果我遇到任何情况,我会更新更多场景。

【问题讨论】:

  • 描述的场景不是 TDD - 因为在 TDD 中你没有私有方法或私有变量。您开始为单元的公共 API 编写测试,而不知道它的实现。您将在重构已经工作和测试过的实现期间创建私有方法和变量。

标签: unit-testing tdd moq


【解决方案1】:

有一个公共方法说Initialize(),它只初始化私有 班的成员。如果它工作正常,如何测试此方法或 不是。

您为其他公共方法编写测试,在测试中调用Initialize 方法,然后调用您正在测试的实际方法并断言其他公共方法正常工作。当Initialize 方法未被调用或它的实现错误时,测试应该失败。

有一个私有方法说 DoSomething() 并被 2 调用 同一类 Caller1() 和 Caller2() 的公共方法。写单元时 测试这两种方法我不能模拟 DoSomething() 因为它 私有的,但是这个方法代码会被测试两次。怎么写 在这种情况下进行代码/测试?

使用 TDD - 测试优先方法,您不应该有私有方法 DoSomething。您为Caller1Caller2 两种方法编写测试,然后当所有必需的测试都通过时,您会注意到实现有一些重复,并通过引入私有方法DoSomething 对其进行重构。它的实现经过了两次测试 - 没关系,您将拥有“双重安全网”。

有一个公共方法 DoSomething() 被称为表单 另一个公共方法 Caller()。 DoSomething() 初始化一个私有的 然后在 Caller() 中使用的成员。我可以模拟 DoSomething() 在测试 Caller() 但无法在私有中设置数据 成员。在这种情况下如何编写代码/测试?

与第一种情况相同。您在测试中调用这两个方法并断言 Caller 方法正常工作。如果Initialize 方法没有被调用或者它的实现是错误的,你的测试将会失败。

【讨论】:

  • 所以简而言之,如果任何代码被重用,那么它将被重新测试。如果没有办法验证方法的结果(没有返回类型,也没有修改公共成员),那么只需通过另一种方法进行测试。
  • 还有一件事要问...是否可以模拟一个从被测方法调用且属于同一类的公共方法?
  • 我不建议这样做。测试应该提供在不改变测试的情况下改变内部逻辑的可能性。这并不总是有效 - 但你应该瞄准那里。
【解决方案2】:

TDD 中有 3 条定律:

  1. 如果没有先编写失败的测试,则不允许您编写任何生产代码,因为生产代码不存在。
  2. 不允许您编写超过足以导致失败的测试;包括编译失败。
  3. 您编写的生产代码不得超过通过当前失败测试的数量。

围绕法律的循环是RED-GREEN-REFACTOR,主要思想之一是通过多个简单的用例(测试)发现您的生产代码

如果我们遵守法律:

  1. (RED)我们编写了第一个用例,并按照您的期望命名了我们的类和方法

例子:

var foo = new Foo()
expect(foo.initialize()).toEqual(false)
  1. (RED) 我们启动了测试,但我们不能!也许,IDE 说我们(嗯,我不知道这个类)所以我们创建类和方法
  2. (绿色)我们编写了最少的代码来通过我们的测试。代码可能非常难看!这一步的目标是在我们进行重构步骤后通过测试

例子:

class Foo {
  initialize() {
    return false
  }
}
  1. (REFACTOR) 在绿色测试之后,我们立即重构我们的生产代码
  2. (REFACTOR) 我们再次启动测试;如果它是绿色的,一切都很好。它是红色的,我们检查重构。并返回 1 直到该功能完成。

为什么每次都重构如此重要?因为我们重构了刚刚写的代码。我们知道它的作用。

因此,在重构阶段,您可以在这里发现是否需要私有方法。如果你有它,在第 5 步启动的测试会隐式检查它。

您可以阅读这些文章:http://blog.cleancoder.com/uncle-bob/2017/03/07/SymmetryBreaking.htmlhttp://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html

有很多关于 TDD 的好内容:您可以观看与 Ian Cooper 或 Bob 大叔 (Robert C. Martin) 的视频

【讨论】:

  • 这些原则是完全正确的,但是当你使用现有的书面代码时,你已经有一些方法可以做一些事情,你必须重用它并添加新的方法,然后在这种情况下我就卡住了在这些情况下。顺便说一句,非常感谢您的宝贵时间。
  • 你能在你的问题中澄清这一点吗?因为我不明白您要在现有代码上进行测试。这是另一种技术。我会更新我的答案
  • 我猜@fabio 的答案是相当合理的,并且对于这个特定的问题来说是很重要的。
猜你喜欢
  • 2018-11-28
  • 2013-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多