使用非静态替换静态方法(200+)调用的有效方法

时间:2015-02-17 00:17:27

标签: c# unit-testing

我正在修复系统中的错误。以下是事实:

  1. 该错误位于密封类Noodles中的方法Yum()中。
  2. Bug方法Yum()是一种静态方法。
  3. Yum()方法在代码库中使用了200多次。
  4. 密封类Noodles确实实现了界面。
  5. 我的问题是,用非静态调用替换静态方法调用的最佳方法是什么,而不会冒可能破坏其他代码的风险。

    我也希望能够测试Noodles类。因为它是一个密封的类,而且方法是静态的,所以模拟选项不在窗口。

    提前致谢。

2 个答案:

答案 0 :(得分:1)

BlorgBeard提出的想法是正确的,尽管你应该实现一个单例模式来实现它。 Jon Skeet在他的书中写了一些关于如何实现单例模式的great examples,给出了几个变体。作为我挑选的例子,我选择了第五版 - 完全懒惰的实例化

在你的具体情况下,我会以这种方式重写你的Noodles课程:

   public sealed class Noodles
   {
       private Noodles()
       {
       }

       public static Noodles Instance { get { return Nested.instance; } }

       private class NestedNoodles
       {
          // Explicit static constructor to tell C# compiler
          // not to mark type as beforefieldinit
          static NestedNoodles()
          {
          }

          internal static readonly Noodles instance = new Noodles();
       }

       public static void Yum() {
          Instance.YumInternal();
       }

       public void YumInternal() {
       //Your code here
       }
  }

关于单元测试,使用密封类和静态方法有点棘手,但这并非不可能。有几种方法。一个是使用包装类,并且鉴于您的类Noodles已经实现了一个接口,它可以是一个解决方案。另一种方法是使用隔离框架,允许在编译后模拟这些类型修改IL(Reflection.Emit,Mono.Cecil等)。看看这个article。这是另一个example

希望它有所帮助。

答案 1 :(得分:0)

假设您想要在所有调用中使用Noodles的实例,您可以进行几次重构(最好使用Resharper或类似的):

  1. Yum的内容解压缩为YumInternal。使YumInternal非静态。

    public static void Yum() {
        NoodlesInstance.YumInternal();
    }
    public void YumInternal() {
        // actual Yum code here
    }
    
  2. 内联方法Yum,以便每次调用它的内容都被替换。

  3. 将方法YumInternal重命名为Yum