【问题标题】:unit test smell单元测试气味
【发布时间】:2010-11-06 14:36:09
【问题描述】:

我正在尝试更改我对 ArcGIS 的单元测试,并开始使用模拟(我使用 rhino)。
当我开始编写测试时,我注意到我必须开始模拟很多对象,并存根很多方法才能通过单个测试。
例如 - 我的控制器首先得到一个RelationshipClass(所以我需要存根IWorkspace和返回的IRelationshipClass),然后也得到一个IFeature(一个存根),最后调用stubRelClass.GetRelatedObjects(stubFeature),返回其他IFeaturesISet

为了让它通过而必须存根这么多对象和方法是否正常?我也感到 就像我真的需要跳过代码(是的 - 我知道我应该先编写测试,我仍在尝试这个),以便弄清楚接下来要存根的内容,以及我应该返回的内容。

我在模拟实现多个接口的 com 类时也遇到了问题。在生产代码中,我在接口之间对它们进行了 QI。如何创建一个在运行时实现这两个接口的模拟?

【问题讨论】:

    标签: unit-testing mocking rhino-mocks arcgis


    【解决方案1】:

    根据您的注入链,是的,有时您必须模拟很多对象。但是,如果您要深入多个级别,则可能表明存在设计错误-依赖于 API 的三层数据的对象可能不是松散耦合的。您应该能够通过在某个时间点返回具有您正在测试的层所需的必要属性的某种假对象来将链条扼杀在萌芽状态。

    您还应该能够在 [SetUp] 方法中进行大部分模拟,然后让每个测试只更改一两件事。

    为了模拟多个接口,Rhino 有 MultiMock 的概念。我相信你所追求的语法是:

    var mock = 
        MockRepository.DynamicMultiMock<MyType>(
                  typeof(Interface1), 
                  typeof(Interface2), 
                  ....);
    

    【讨论】:

    • 关于引入一个削减深层层次的对象 - 它会“拯救”我免于模拟更多对象(因为这个对象会覆盖它们),但我仍然需要模拟相同数量的方法,对吗?还是我弄错了?
    • 重点不是“拯救你”免于模拟更多对象。关键是测试试图告诉你其中缺少一个概念,这就是它如此复杂的原因。
    【解决方案2】:

    对我来说,这听起来像是无法测试的代码,这是一种气味 :-(

    我建议阅读http://misko.hevery.com/code-reviewers-guide/。作者是教练,负责在测试领域教谷歌开发者。在文章中,他展示了如何编写可测试和不可测试的代码。

    进一步推荐阅读: Clean Code (Robert C. Martin) - 主要关注如何编写干净的(对应于可测试的)代码。 有效地使用遗留代码 (Michael Feather) - 展示了控制未经测试和不可测试的代码的方法。

    【讨论】:

    【解决方案3】:

    这可能是高耦合的标志 - 这反过来意味着需要减少依赖关系(这将提高设计和可测试性)。作为粗略的指导方针,一个对象最多应该有 4-6 个协作者。任何超出此范围的事情都会引起我的警觉。

    How are Mocks meant to be used?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-12
      • 2011-07-24
      • 2011-06-08
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多