Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用静态方法进行模拟?_C#_.net_Mocking_Interface_Static Methods - Fatal编程技术网

C# 如何使用静态方法进行模拟?

C# 如何使用静态方法进行模拟?,c#,.net,mocking,interface,static-methods,C#,.net,Mocking,Interface,Static Methods,我不熟悉模拟对象,但我知道我需要让我的类实现接口来模拟它们 我遇到的问题是,在我的数据访问层中,我想要静态方法,但我不能在接口中放置静态方法 最好的解决办法是什么?我应该只使用实例方法(这似乎是错误的)还是有其他解决方案?我会使用方法对象模式。拥有此的静态实例,并在静态方法中调用它。根据您的模拟框架,应该可以为测试创建子类 i、 e.在您使用静态方法的课堂上: private static final MethodObject MethodObject=new MethodObject(); 公

我不熟悉模拟对象,但我知道我需要让我的类实现接口来模拟它们

我遇到的问题是,在我的数据访问层中,我想要静态方法,但我不能在接口中放置静态方法


最好的解决办法是什么?我应该只使用实例方法(这似乎是错误的)还是有其他解决方案?

我会使用方法对象模式。拥有此的静态实例,并在静态方法中调用它。根据您的模拟框架,应该可以为测试创建子类

i、 e.在您使用静态方法的课堂上:

private static final MethodObject MethodObject=new MethodObject();
公共静态无效剂量测定法(){
methodObject.doSomething();
}
您的方法对象可以是非常简单、易于测试的:

公共类MethodObject{
公共无效剂量测定法(){
//做你的工作
}
}

是的,您使用实例方法。静态方法基本上说,“有一种方法可以实现这个功能——它不是多态的。”模仿依赖于多态性


现在,如果您的静态方法在逻辑上不关心您正在使用的实现,那么它们可能能够将接口作为参数,或者可能在根本不与状态交互的情况下工作——但是,否则您应该使用实例(可能还有依赖项注入来将所有内容连接在一起).

尽可能使用实例方法


在不可能使用实例方法的情况下,使用公共静态函数[T,U](可以替代模拟函数的静态函数引用)。

您可能试图在太深的起点上进行测试。不需要创建测试来单独测试每个方法;私有和静态方法应该通过调用公共方法进行测试,然后公共方法依次调用私有和静态方法

假设您的代码如下所示:

public object GetData()
{
 object obj1 = GetDataFromWherever();
 object obj2 = TransformData(obj1);
 return obj2;
} 
private static object TransformData(object obj)
{
//Do whatever
}
您不需要针对TransformData方法编写测试(您也不能这样做)。而是为GetData方法编写一个测试,该方法测试TransformData中完成的工作。

我发现了一个很好的例子,其中有一些关于如何做到这一点的例子:

  • 将类重构为实例类并实现接口

    您已经声明不想这样做

  • 将包装器实例类与静态类成员的委托一起使用

    这样,您可以通过委托来模拟静态接口

  • 使用具有调用静态类的受保护成员的包装器实例类

    这可能是在不重构的情况下最容易模拟/管理的方法,因为它可以继承和扩展


  • 一个简单的解决方案是允许通过setter更改静态类的实现:

    class ClassWithStatics {
    
      private IClassWithStaticsImpl implementation = new DefaultClassWithStaticsImpl();
    
      // Should only be invoked for testing purposes
      public static void overrideImplementation(IClassWithStaticsImpl implementation) {
         ClassWithStatics.implementation = implementation;
      }
    
      public static Foo someMethod() {
        return implementation.someMethod();
      }
    
    }
    

    因此,在测试设置中,您可以使用一些模拟接口调用
    overrideImplementation
    。好处是您不需要更改静态类的客户端。缺点是您可能会有一些重复的代码,因为您必须重复静态类的方法及其实现。但有时静态方法可以使用提供基本功能的ligther接口。

    问题是,当您使用第三方代码时,它是从您的方法之一调用的。我们最后要做的是将其包装到一个对象中,并使用dep inj调用passing in,然后您的单元测试可以模拟第三方静态方法,并使用它调用setter。

    您对该模式有什么好的参考吗?我不知道该怎么做。呃,事实上没有。我不确定这个名字是不是我编造的,或者它被认为更像是一种习语而不是一种模式,但我看不到谷歌有任何像样的参考资料。我会继续看的。谢谢,这个例子帮助我理解了你的意思。这样做实际上扼杀了所有关于使用静态方法的想法。这不是称为singleton吗?只是一个小问题,如果要以静态方式访问,实现不必声明为静态的吗?太棒了,谢谢,第三个选择非常适合我