【问题标题】:Is having a unit test that is mostly mock verification a smell?有一个主要是模拟验证的单元测试是一种气味吗?
【发布时间】:2011-06-08 06:46:48
【问题描述】:

我有一个连接其他三个服务的类,专门设计用于使其他服务的实现更加模块化,但我的大部分单元测试逻辑都在模拟验证中。有没有办法重新设计来避免这种情况?

Python 示例:

class Input(object): pass

class Output(object): pass

class Finder(object): pass

class Correlator(object): pass
  def __init__(self, input, output, finder):
    pass
  def run():
    finder.find(input.GetRows())
    output.print(finder)

然后我必须模拟输入、输出和查找器。即使我确实做了另一个抽象并从 Correlator.run() 返回了一些东西,它仍然需要作为模拟进行测试。

【问题讨论】:

  • 您的问题到底是什么?我有最多需要八个依赖项的类...如果您的设计是正确的并且您认为您的抽象是一致的,我不会更改您的代码。
  • 我认为困扰我的事情是该类的唯一目的是集成,因此最好的测试方法是集成测试。随着架构的成熟,我总是首先争取独立的单元测试,然后是集成测试。我想我只好放过这个了。

标签: python unit-testing language-agnostic tdd


【解决方案1】:

没有理由只使用单元测试——也许集成测试对这种情况更有用。正确初始化所有对象,稍微使用主类,并断言(可能很复杂)结果。这样,您将测试接口、输出可预测性以及其他在堆栈中更重要的事情。我以前用过这个,发现很难集成测试的东西可能有太多的属性/参数或太复杂/格式错误的输出。

【讨论】:

    【解决方案2】:

    问问自己:在这个特定的测试用例中,您到底需要检查什么?如果此检查不依赖于其他非 dummy 类,那么您就可以了。

    但是,从某种意义上说,很多模拟通常是一种气味,您可能正在尝试测试集成而没有实际进行集成。因此,如果您假设该类通过了模拟测试,那么使用真实类就可以了,那么您必须编写更多测试。

    就我个人而言,我根本不会写很多单元测试。我是 Web 开发人员,我更喜欢功能测试,通过 HTTP 请求测试整个应用程序,就像用户一样。您的情况可能不同

    【讨论】:

      【解决方案3】:

      乍一看,这确实看起来嘲笑的程度变得很大。如果您使用的是动态语言(我在这里假设是,因为您的示例是在 Python 中),我会尝试构建生产类的任何一个子类,其中最有问题的方法被覆盖并呈现模拟数据,所以你会获得生产和模拟代码的混合。如果您的代码路径不允许实例化对象,我会在返回模拟数据的替换方法中尝试 monkey patching

      天气与否这是否是代码异味也取决于模拟数据的质量。根据我的经验,进入调试器并复制粘贴已知的正确数据或从网络中嗅探是确保这一点的首选方法。

      集成与单元测试也是一个经济问题:用集成/功能测试代替单元测试有多痛苦?系统规模越大,轻量级模拟的收益就越大,因此,单元测试也就越多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-06
        • 2012-09-12
        • 1970-01-01
        • 2012-03-01
        • 2014-05-07
        • 1970-01-01
        • 2011-11-17
        • 1970-01-01
        相关资源
        最近更新 更多