【问题标题】:Is it possible to test a local value using a junit test?是否可以使用 junit 测试来测试本地值?
【发布时间】:2011-10-11 04:02:33
【问题描述】:

有时我想测试方法中的中间值。但是方法不能拆分。所以我想知道JUnit是否只能将一个方法作为一个单元进行测试。如果我可以在方法中放置断点之类的东西,并获取本地值并对其进行断言,那就更好了。如果不可能,这种问题怎么解决。

【问题讨论】:

    标签: android unit-testing testing junit tdd


    【解决方案1】:

    添加断点并不是真正的单元测试,实际上根本不是测试。您可以将其称为检查,但没有检查驱动开发之类的东西。

    无论如何,刚接触单元测试的人经常发现这个问题,他们想测试私有或本地值,让它成为一个变量或方法。事实上,当我开始 TDD 时,我自己已经完全被它分阶段了。但问题是,在单元测试中,目的是对特定功能和所有可能的结果进行黑盒测试。黑盒子里面发生的事情不是你关心的,你也不需要对它进行单元测试。

    如果您想测试一个中间值,那么您的方法可能太长,应该分成两个或多个可测试的小方法。如果无法完成,那么您不必担心对其进行测试。

    如果该中间值是从另一个公共方法获取它的值,那么它是您要在单独的单元测试中测试的 那个 方法,而不是您当前正在测试的方法中的值。

    【讨论】:

    • 非常感谢,您的回答很棒。我还遇到了另一个问题,当我测试一个关于数据库的模块时,测试总是改变数据库中的值。但我希望它发生。那么有没有办法在setUp中备份数据库,在tearDown中恢复数据库(我不想写备份代码,让系统自动完成)。
      测试gui怎么样? TDD 是否也适合 gui 测试?我发现很难获得价值。
      ps:现在我正在开发一个 android 项目。再次感谢。
    • 不客气。TDD 不适合基于 Web 的应用程序的 gui,您可以使用 selinium 或 windmill(在 google 上搜索)用于 android 我不测试 gui,不确定人们一般在做什么。至于数据库问题,您需要使用模拟框架,不要担心它们不是很复杂,看看code.google.com/p/android-mockcode.google.com/p/mockito 的想法是,您永远不会在数据库中保留任何东西,而是假装(模拟)就好像它已经发生了一样。单元测试不应该击中作为集成测试工作的数据库。话虽如此,你可以回滚
    • 测试拆解中的交易。但这应该是另一个问题 :) 询问另一个显示您的代码并询问您如何回滚事务的人。我很快就会离开,但我肯定会有其他人从社区那里了解到这一点。但就像我说的那样,我从来没有打过实际的数据库,因为单元测试不应该。只是模拟一下:) 祝你好运,我相信你会喜欢的有趣的东西。
    • 但我认为android中的很多数据只出现在GUI中。例如,我建立了一个列表视图来显示我从数据库查询的结果。我想测试数据是否被正确查询。所以我认为这是获取特定 TextView 并使用 TextView.getText() 方法的唯一方法,然后将文本与期望值进行比较。
    • 似乎还有另一种方式。只需将生成值的代码作为方法拉出来,然后测试方法的返回值。但我不喜欢这样做,因为这些语句不适合提取方法。
    【解决方案2】:

    您的问题导致了对 TDD 中 D 的解释。特别是当您使用 TDD 来表示“测试驱动设计”时(尽管有些人更喜欢“测试驱动开发”这个短语)。

    正如@Shahzeb 指出的那样,也许你的方法太长了,应该分成两种方法,一种产生中间值,另一种将其作为输入。我们以这种方式思考代码的倾向实际上是由测试驱动。我们代码的设计更好,因为我们为了能够测试它们而分离关注点。因此,您提出了一个很好的问题(其简短的回答是“否”),这些问题可以让 TDD 改进我们的设计。

    【讨论】:

    • 卡尔说得非常好,准确而有见地。
    • 感谢您的回答。但是当我编写一个太长而无法测试的方法时,我将它分成两个私有方法。我认为问题仍然存在,因为我似乎无法测试私有方法。有没有比将私有更改为公共更好的方法来解决这个问题?
    【解决方案3】:

    这个想法是您根本不测试私有(中间)值,因为它在外部并不重要(这就是您明智地将其保持私有的原因。)私有值表示您设置的对象中的某些状态现在的意图是它会影响将来对您的公共接口的调用,对吗?所以改变你的一个测试来打两个电话。让第一次调用执行任何需要的操作,按照您认为的方式设置状态,然后进行第二次调用,并查看设置该变量时结果是否符合您的预期。如果它真的是私有的,那么单元测试它的值是什么并不重要——只要它在正确的时间正确地产生所需的结果。但是这个建议带有一个警告:它正在悄悄进入你可能要求单元测试做的比一个单元的测试价值更多的领域。

    另一个观察:您说您的方法“不能拆分”,但没有提供解释原因。如果您无法更改设计,听起来更像是您可能试图将单元测试插入遗留代码,而不是执行测试驱动开发。没关系,您不必在这里放弃 TDD,但也许还有其他方法需要考虑。一旦你通过了测试,在 TDD 中,这就是你需要重构方法的部分。你在谈论一个中间值的事实表明你的方法有太多的责任。考虑使用提取方法将功能的更简洁部分封装成更小、可测试的服务方法。

    如果这不是您想要完成的任务,那么您尝试执行的测试可能是“想得太大”了。也许您尝试做的测试更多的是验收测试。同样,这很好,验收测试也很重要,但它不再是真正的单元测试了。

    【讨论】:

    • 您的回答很棒。但是我仍然无法根据现有知识获得意义,我将继续学习 TDD 以更好地理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 2017-09-18
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多