【问题标题】:What should I consider when choosing a mocking framework for .Net [closed]为 .Net 选择模拟框架时应该考虑什么 [关闭]
【发布时间】:2010-10-13 03:49:30
【问题描述】:

有很多针对 .Net 的模拟框架。没有明确的赢家在各个方面都取代了其他人。领先的模拟框架也有许多不同的风格

学习所有模拟框架所需的时间足以决定使用哪个是不合理的。我认为我们还没有达到可以谈论最好的模拟框架的阶段。那么我应该问关于项目和我自己的哪些问题,以帮助决定在特定情况下使用的最佳模拟框架?

了解您选择当前使用的模拟框架的原因以及您是否仍然满意该选择也很有用。

在比较模拟框架的风格时,是否有有用的词汇可供使用?

注意:我将这个问题限制在.Net,因为Java没有属性或lambda表达式,所以我希望模拟框架对.Net比Java更好)

到目前为止的总结:

  • 如果你需要模拟静态方法,或者 没有虚拟方法,然后是唯一的 合理的选择是TypeMock,但它不是免费的,也不会驱使您走向好的设计。
  • Rhino Mocks 是一个很好的选择,如果你 正在做 TDD,例如你的对象 希望模拟实现接口。目前它似乎是“市场领导者”
  • Moq (introduction) 如果你是 使用 .NET 3.5 Moq 可能在新项目中使用 Rhino Mocks

我从这个摘要中遗漏了什么?

如果您使用的是 .NET 3.5,那么是什么促使您在 Rhino MocksMoq 之间做出选择?


另见:

What should I consider when choosing a dependency injection framework for .NET?”可能也很有趣,因为它问的是问题的“另一面”。

【问题讨论】:

标签: .net unit-testing tdd mocking


【解决方案1】:

那么我应该通过询问项目和我自己的哪些问题来帮助决定在给定案例中使用的最佳模拟框架?

关于该项目,您应该问的问题是:该项目是按照 SOLID 原则开发的,还是没有?这是一个松耦合、高内聚的项目吗?在构建项目时是否使用了良好的 OO 原则?是否使用了依赖注入容器?系统是否以按合同设计的方法进行编码(彻底利用接口)?

如果您对这些问题的回答是肯定的,那么您可以使用像 RhinoMocks 这样的模拟框架,这就是一些人所说的“有意见的”框架。 RhinoMocks 和其他一些模拟框架对于如何设计系统以便模拟对象有非常强烈的意见。像 RhinoMocks 这样的框架希望您的项目以某种方式设计。当您以正确的方式构建代码(没有密封类、没有静态、大量使用接口、类上的虚拟方法等)时,使用 RhinoMocks 进行模拟肯定会容易得多。

如果您对这些问题的回答是否定的,或者如果您正在使用具有许多高度耦合类的遗留系统,那么您唯一的选择就是 TypeMock,它可以模拟任何东西。

了解您选择当前使用的模拟框架的原因以及您是否仍然满意该选择也很有用。

我选择 RhinoMocks 是因为在当时(3 年多以前),它显然是最成熟、功能最多的模拟框架。我一直使用它,因为它已经进化了,这让我的生活变得更加轻松(AutoMocking 容器的出现是朝着效率迈出的一大步)。

除了功能集和易用性之外,我喜欢 RhinoMocks 的地方在于它引导我在代码中进行更好的设计。我不是一个完美的程序员,我会在设计上犯错误。但是像 RhinoMocks 和 NHibernate 这样的工具可以帮助我做出更好的设计,因为当我确实犯了错误并创建了糟糕的设计时,使用这些工具会变得很痛苦。例如,如果您有一个糟糕的数据库设计,那么使用 NHibernate 会很痛苦。如果你有一个糟糕的类设计,不使用接口,不使用 IoC 等等,使用 RhinoMocks 会非常痛苦。

我喜欢 RhinoMocks,因为它最终帮助我成为一个更好的开发人员,不仅仅是因为我正在测试我的代码,还因为我正在以更好的方式塑造我的代码 - 设计它。

【讨论】:

  • 一个很好的答案,在很多情况下都是正确的,但重要的是要记住,技术上好的代码不一定映射到业务的限制。伟大的设计是美妙的,但可能很耗时,..有时只是没有时间变得如此健壮,但您仍然需要一个足够灵活的模拟框架来完成工作。
  • 不幸的是,我找不到任何证据来支持“它引导我在我的代码中进行更好的设计”这样的说法。相反,我的经验告诉我,它会引导您进行过度设计的设计,并经常阻碍良好的设计。
【解决方案2】:

对于 .NET 3.5 项目,我更喜欢 Moq。它使用简单,根据我的经验,它有助于生成干净清晰的单元测试。

您不能在同一个项目中使用多个模拟框架并没有技术原因。当然,标准化很好,但某些测试可能更适合某些框架。

【讨论】:

    【解决方案3】:

    免责声明——我为Typemock工作

    我不同意“Typemock 不会驱使您做出好的设计”。推动设计好坏的开发人员是您,而不是您使用的工具。获得完成工作的工具,让你更有效率,但好的设计是你自己的责任。如果您认为将所有类型的抽象包装在您的代码中,只是为了测试,那就去做吧,但您可能不会想出一个“好的”设计。它可能比你现在的设计更复杂。

    【讨论】:

      【解决方案4】:

      在为 .Net 选择模拟框架时应该考虑什么

      除了您要测试的代码库的设计之外,要考虑的另一个方面是使用模拟时您的测试的可读性。

      在这方面,我对NSubstitute 投了票——这是一种较新的模拟框架之一,它具有非常富有表现力的 API(无 lambdas)以及与 Moq 和 Rhino Mocks 相当的功能。它最近达到了 1.0 版。

      一个使用示例(来自 NSubstitute 主页):

      //Create:
      var calculator = Substitute.For<ICalculator>();
      
      //Set a return value:
      calculator.Add(1, 2).Returns(3);
      Assert.AreEqual(3, calculator.Add(1, 2));
      
      //Check received calls:
      calculator.Received().Add(1, Arg.Any<int>());
      calculator.DidNotReceive().Add(2, 2);
      
      //Raise events
      calculator.PoweringUp += Raise.Event();
      

      使用RhinoMocksMoq 和 NSubstitute 的测试的可读性的详细比较在here 中给出。

      【讨论】:

        【解决方案5】:

        stubs 看起来很有趣,我认为它可能随 .NET V4 一起提供。我不知道你需要使用开发者工作室的女巫版。目前可以从以上链接下载。

        Stubs 是一个轻量级的框架,用于 .NET 中的测试存根和弯路 认真地基于代表,类型 安全、可重构和源代码 生成。存根被设计支持 Code Contracts 运行时编写者和 为 Pex 提供最小的开销 白盒分析。可以使用存根 在任何 .NET 方法上,包括 密封中的非虚拟/静态方法 类型。

        (我已将此作为答案发布,然后将其添加到问题中,因为我从未使用过 Stabs 并且只花了几分钟时间查看它)

        【讨论】:

          【解决方案6】:

          RhinoMock 几乎是最先进的 .NET 模拟框架。不能出错。如果您愿意,我想您可以将其“风格”视为“万事通”。

          来自他们的web site

          Rhino Mocks 提供什么?

          • 针对预期的显式记录和回放模型。
          • 自然排列、动作、断言语法
          • 支持 .Net 2.0 和 .Net 3.5
          • 使用强类型模拟。
          • 对方法设置操作、返回特定值或引发异常。
          • 预期基于:
            • 参数匹配
            • 约束匹配
            • 使用您自己的代码验证预期参数的自定义回调

          【讨论】:

            【解决方案7】:

            我会推荐 FakeItEasy。这是一个真正描述性的模拟框架,允许非常容易地阅读和模拟接口。它有一个活跃的开源社区并且运行良好。

            【讨论】:

              【解决方案8】:

              我用的是Telerik JustMock,它是一个非常专业且简单的mock框架,文档很好。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-10-13
                • 2011-02-14
                • 1970-01-01
                • 2022-01-24
                • 1970-01-01
                • 2013-04-26
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多