在遗留应用程序中将静态 class 转换为常规 class 以启用模拟的简单方法

A simple way to convert a static class to regular class in legacy applications to enable mocking

传统应用程序中的静态 类 很难在单元测试中使用,因为您无法模拟它们。

将它们在整个应用程序中转换为使用 Interafce 的常规 类 的简单方法是什么?

最简单快速的方法:编写一个包装器class,其中包含调用静态方法的虚拟方法。


有约束和无约束的模拟框架。

前者:Moq、NSubstitute、FakeItEasy 只允许模拟虚拟成员。

而是使用不受约束的模拟框架。其中有几个:TypeMock、JustMock、MS Fakes、Prig、Ionad.Fody、Pose、Harmony、MethodRedirect。与受限框架不同,它们允许您替换静态方法和 classes、模拟私有成员等

分两步执行此操作最简单且风险较小。

第一步重复且缺乏创意,可以分配给初级工程师,甚至可以用小程序完成。

对于每个 class,请执行以下步骤:

  1. 从所需的方法和属性中删除 static 关键字。

  2. 添加名为 Instance 的静态成员,其中包含 class 的实例。是的,我们正在制作 singleton.

     //Old class
     static class MyHelpers
     {
         public static string Foo(string x) {  /* Implementation */ }
     }
    
     //New class
     class MyHelpers
     {
         public static MyHelpers Instance { get; } = new MyHelpers();
         public string Foo(string x) { /* Implementation */ }
     }
    
  3. 在您的其余代码库中,将静态调用替换为对实例的调用。

     //Old code
     MyHelpers.Foo("Hello world");
    
     //New code
     MyHelpers.Instance.Foo("Hello world");
    
  4. 编译以确保您没有遗漏任何地方

  5. 测试并签入源代码

第二步是可选的。我们真的想摆脱那些 Instance 关键字,因为它们会破坏 IoC(如果你在代码库中保留单例,其他工程师会取笑你)。这需要你

  1. 添加一个或多个接口

  2. 安排 class 注入或以其他方式在任何使用 Instance 的地方可用。

  3. Search/replace 从所有调用中删除“.Instance”。

第二步需要多思考一点,应该分配给更中级的工程师。如果您的代码库很大,您可以随着时间的推移这样做,或者只是在您接触代码时从战术上进行更改。