代码之家  ›  专栏  ›  技术社区  ›  Ian Boyd

可以在不更改任何代码的情况下,对最初设计为不进行测试的代码进行单元测试吗?

  •  3
  • Ian Boyd  · 技术社区  · 14 年前

    除非代码设置为要测试,否则您不能测试代码,这是普遍接受的吗?

    一个假设的代码:

    public void QueueOrder(SalesOrder order)
    {
       if (order.Date < DateTime.Now-20)
          throw new Exception("Order is too old to be processed");
       ...  
    }
    

    有些人会考虑将其重构为:

    protected DateTime MinOrderAge;
    {
       return DateTime.Now-20;
    }
    
    public void QueueOrder(SalesOrder order)
    {
       if (order.Date < MinOrderAge)
          throw new Exception("Order is too old to be processed");
       ...
    }
    

    注: 你可以想出更复杂的解决方案;包括 IClock

    更改上述代码的问题是代码已更改。代码已更改,而客户未要求更改。任何改变都需要召开会议和电话会议。所以我觉得不测试任何东西都比较容易。

    如果我不愿意/不能做出改变:是否会使我无法执行测试?

    上面的伪代码可能看起来像C#,但这只是为了便于阅读。这个问题是语言不可知论的。

    假设的代码片段、问题、重构的需要和重构都是假设的。如果你对我的不满意,你可以插入你自己的假设代码样本。

    注:

    注: 代码是假设的,但任何答案都不是。这个问题不是主观的:因为我相信有答案。


    更新:

    但是我不能保证添加一个新的受保护的方法 ,如果该类位于DLL中,则我刚刚引入了访问冲突。

    7 回复  |  直到 14 年前
        1
  •  4
  •   Eric Petroelje    14 年前

    答案是肯定的,有些代码需要更改才能进行测试。

    但可能有很多代码可以在不需要更改的情况下进行测试。我将首先专注于为那些东西编写测试,然后在其他客户需求给您以可测试的方式重构它的机会时为其他东西编写测试。

        2
  •  1
  •   Ned Batchelder    14 年前

    代码可以从一开始就编写成可测试的。如果不是从一开始就考虑可测试性,你仍然可以测试它,你可能会遇到一些困难。

    在假设的代码中,可以通过创建一个日期远在过去的SalesOrder来测试原始代码,也可以模拟DateTime.Now。如您所示对代码进行重构对于测试来说更好,但这并不是绝对必要的。

        3
  •  1
  •   frast    14 年前

    如果您的代码不是设计用来测试的,那么测试它就更困难了。在您的示例中,您必须重写DateTime.Now方法,这显然不是一项简单的任务。

    我认为在代码中添加测试没有什么价值,或者不允许更改现有代码,那么就不应该这样做。

        4
  •  1
  •   orangepips 111111    14 年前

    可以使用模拟对象框架对原始示例进行单元测试。在本例中,我将模拟SalesOrder对象多次,每次配置不同的日期值,然后测试。这样可以避免更改任何发布的代码,并允许您验证有关的算法,即订单日期在过去不太远。

    Working Effective with Legacy Code .

        5
  •  0
  •   Ionuț G. Stan    14 年前

        6
  •  0
  •   Thomas Weller    14 年前

    这类代码的问题始终是,它正在创建并依赖于许多静态类、框架类型等。。。

    为所有这些对象“注入”赝品的一个非常好的解决方案是Typemock隔离器(这是一个商业化的解决方案,但值每一分钱)。所以是的,你当然 测试遗留代码,它是在不考虑可测试性的情况下编写的。我用Typemock完成了一个大项目,取得了很好的效果。

    除了Typemock之外,您还可以使用免费的MS-Moles框架,其功能基本相同。只是它有一个非常不直观的API,而且很难学习和使用。

    哦。
    托马斯

        7
  •  0
  •   manolowar    14 年前