我还有最后一节课,大概是这样的:

public final class RainOnTrees{

   public void startRain(){

        // some code here
   }
}

我在其他一些类中使用这个类,像这样:

public class Seasons{

   RainOnTrees rain = new RainOnTrees();

   public void findSeasonAndRain(){

        rain.startRain();

    }
}

在我的JUnit测试类Seasons.java中,我想模拟RainOnTrees类。我怎么能用Mockito做到这一点?


当前回答

为运行mockito成功添加这些依赖项:

testImplementation org.mockito: mockito-core: 2.24.5 testImplementation“org.mockito: mockito-inline: 2.24.5”

其他回答

只有在Mockito v2中才可以模拟final/static类/方法。

添加到你的gradle文件:

testImplementation 'org.mockito:mockito-inline:2.13.0'

这是不可能与Mockito v1,从Mockito常见问题:

Mockito的局限性是什么 需要java1.5 + 不能模拟最终类 ...

根据这个GitHub问题,mockito-android不支持mock final类。您应该使用Mockk代替它。

对于单元测试和ui测试,都可以毫无问题地使用Mockk。

实际上有一种方法,我用来监视的。只有满足两个前提条件,它才会为你工作:

使用某种DI注入final类的实例 Final类实现了一个接口

请回顾Effective Java中的第16项。你可以创建一个包装器(不是final)并将所有调用转发给final类的实例:

public final class RainOnTrees implement IRainOnTrees {
    @Override public void startRain() { // some code here }
}

public class RainOnTreesWrapper implement IRainOnTrees {
    private IRainOnTrees delegate;
    public RainOnTreesWrapper(IRainOnTrees delegate) {this.delegate = delegate;}
    @Override public void startRain() { delegate.startRain(); }
}

现在你不仅可以模仿你的最后一个类,还可以监视它:

public class Seasons{
    RainOnTrees rain;
    public Seasons(IRainOnTrees rain) { this.rain = rain; };
    public void findSeasonAndRain(){
        rain.startRain();
   }
}

IRainOnTrees rain = spy(new RainOnTreesWrapper(new RainOnTrees()) // or mock(IRainOnTrees.class)
doNothing().when(rain).startRain();
new Seasons(rain).findSeasonAndRain();

正如其他人所说,这不会在Mockito的盒子外工作。我建议使用反射来设置测试代码正在使用的对象上的特定字段。如果您发现自己经常这样做,可以将此功能打包到一个库中。

说句题外话,如果你是那个给课程打期末分数的人,那就别这么做了。我遇到这个问题是因为我正在使用一个API,其中所有内容都被标记为final,以防止我合理地需要扩展(mock),我希望开发人员没有假设我永远不需要扩展该类。

对于最终类,添加以下内容以模拟和调用静态或非静态。

1-添加到职业等级 @SuppressStatucInitializationFor(value ={带有包的类名}) PowerMockito.mockStatic(classname.class)将模拟类 3-然后使用你的when语句在调用这个类的方法时返回模拟对象。

享受