如何用静态方法嘲笑?(How to mock with static methods?)

2019-07-21 06:07发布

我是新来嘲笑的对象,但我明白,我需要让我的类实现以嘲笑他们的接口。

我遇到的问题是,在我的数据访问层,我想有静态方法,但我不能把静态方法的接口。

什么是解决这个问题的最好方法? 我应该使用实例方法(这似乎是错误的),或者是有另一种解决方案?

Answer 1:

我想使用的方法对象的图案。 对此有静态实例,并调用它的静态方法。 它应该是可能的子类进行测试,这取决于你的模拟框架。

即,与静态方法类有:

private static final MethodObject methodObject = new MethodObject();

public static void doSomething(){
    methodObject.doSomething();
}

和你的方法对象可以是一个很简单,很容易测试:

public class MethodObject {
    public void doSomething() {
        // do your thang
    }
}


Answer 2:

是的,你使用实例方法。 静态方法基本上说,“还有就是要实现这种功能的一种方法 - 它不是多态。” 嘲讽依靠多态性。

现在,如果您的静态方法在逻辑上并不关心你用什么样的实现,他们可能可以把接口作为参数,或者是工作,而在所有与国家互动 - 但除此之外,你应该使用实例(也可能依赖注入到有线一切在一起)。



Answer 3:

我发现了一个博客通过谷歌就如何做到这一点一些很好的例子:

  1. 重构类是实例类,并实现一个接口。

    你已经说过你不希望这样做。

  2. 使用包装类的实例与代表静态类成员

    这样做,你可以模拟通过委托静态接口。

  3. 使用带有保护成员,其调用静态类的包装实例类

    这可能是最简单的嘲笑/管理不重构,因为它可以只是从继承和扩展。



Answer 4:

你可能会想在过深的出发点来进行测试。 测试不需要被创建单独地测试每一个方法; 私有与静态方法应该调用的公共方法是再调用私有和静态的依次进行测试。

因此,可以说您的代码是这样的:

public object GetData()
{
 object obj1 = GetDataFromWherever();
 object obj2 = TransformData(obj1);
 return obj2;
} 
private static object TransformData(object obj)
{
//Do whatever
}

你并不需要编写针对TransformData方法的测试(你不能)。 相反,写一个测试在TransformData所做的工作GetData方法测试。



Answer 5:

使用实例方法在可能的情况。

使用公共静态函数功能[T,U](静态函数,可用于替代模拟函数的引用),其中的实例方法是不可能的。



Answer 6:

一个简单的解决办法是允许通过一个设置来改变静态类的实现:

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接口,提供基础的funcionality。



Answer 7:

当你使用第三方代码,并将其从你的方法之一,叫你的问题是。 我们落得这样做是包裹它的对象,并调用它传递与DEP注射,然后你的单元测试可以模拟第三方静态方法调用的setter吧。



文章来源: How to mock with static methods?