为什么我们需要像Easymock,JMock或Mockito这样的模拟框架?

Pra*_*eth 10 tdd unit-testing easymock mocking stubs

我们在单元测试中使用手写存根,我正在探索在我们的项目中需要像EasyMock或Mockito这样的Mock框架.

我没有找到从手写存根切换到Mocking框架的令人信服的理由.

任何人都可以回答为什么当他们已经使用手写的模拟/存根进行单元测试时会选择模拟框架.

谢谢

Fin*_*las 15

简单的答案是,我们并不需要他们.

我们也不需要其他现有框架,但使用Mocking框架可以让我们的生活更轻松.作为开发人员,我们可以将更多时间花在手头的问题上,而不是创建或执行模拟框架可以执行的操作.

" 我没有找到一个令人信服的理由从手写存根转换到Mocking框架."

我完全一样.我为什么要费心学习模拟框架?手写的存根很好.

我想到了几点,主要是因为一段时间后你的测试变得模糊不清.使用手写存根时所指的内容称为测试扩展.您可以扩展代码以启用模拟框架.换句话说,您将代码写入存根,或根据发生的情况返回值.这需要时间和精力.更不用说空间了.一个模拟框架可以在一条线上完成所有这些.

模拟框架的好处是:

  • 更容易(主观,但过了一段时间你不会写手写的实现)
  • Less Code(框架允许您在行中创建模拟,而不是完整的类声明)
  • 跟随DRY(你最终不会重复模拟实现)

当您需要模拟对象时,最大的好处就来了.必须手写代码来检查方法是否被调用,多少次等等本身就是一个迷你任务.如果其他人已经这样做,并创建了一个经过充分测试,记录良好的框架,那么不使用它就没有意义.就像任何框架一样,没有它就可以顺利进行,但有时使用正确的工具可以使工作变得更加容易.


Mic*_*rdt 9

您可能想阅读Martin Fowler的Mocks Are Not Stubs文章.基本的区别是:

  • 存根的工作是将已知结果返回给所有调用
  • 模拟另外期望调用以特定顺序进入,具有特定参数,并且当不满足这些期望时将抛出异常.

存在一些无法使用存根测试的错误情况.另一方面,使用模拟的测试通常不太稳定.

虽然可以通过合理的努力手动编写存根,但Mocks需要更多的工作.一个好的模拟框架也可以使编写存根更快更容易.


Pét*_*rök 2

我以同样的方式开始(手工编写模拟),现在我几乎完全切换到 EasyMock。

我发现使用 EasyMock 通常既更快又更灵活。

通常,当我第一次需要模拟时,我可以使用 EasyMock 将其包含在几行代码中,而我需要手动实现所需的接口(很公平,这可以由像 IntelliJ 这样的 IDE 生成),然后添加必要的代码以产生所需的响应和/或允许感知对其调用的影响。

好吧,有人可能会说,这只是一次性成本。下次我可以愉快地重复使用手写的模拟......我发现情况往往并非如此。在另一个测试中,我可能需要模拟具有不同行为的同一类。例如,调用不同的方法,和/或期望不同的结果。一种特定情况是模拟预计在一个测试用例中抛出异常,但在另一个测试用例中不会抛出异常。很好,我可以向其中添加一些动态控制行为的参数。然后,对于下一个测试,更多的参数来控制更多的行为......所以我最终得到了一个更加复杂的模拟实现,这是对更多单元测试的依赖 - 也带来了无意中破坏旧测试的风险。

与此相反,使用 EasyMock,我可以为每个测试独立配置我的模拟。因此,该行为在单元测试代码本身内是明确控制和可见的,并且不存在副作用的风险。

更不用说,如果需要的话,使用 EasyMock 您可以验证所需的方法是否按所需的顺序调用(我时不时也会这样做)。手动实现这一点(尤其是以通用方式)会很麻烦,而且没有任何额外的好处。