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

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做到这一点?


当前回答

在构建文件中添加以下内容:

如果使用gradle: build.gradle

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

如果使用maven: pom.xml

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>2.13.0</version>
    <scope>test</scope>
</dependency>

这是一个使mockito与final类一起工作的配置

如果您面临无法初始化内联字节伙伴模拟生成器。(Android不支持这个模拟生成器。) 将字节伙伴依赖项添加到构建中。gradle文件:

testImplementation 'net.bytebuddy:byte-buddy-agent:1.10.19'

src: https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy

其他回答

我克服了这条信息:

org.mockito.exceptions.base.MockitoException: 不能模拟/间谍类org.slf4j.impl.Log4jLoggerAdapter Mockito不能模仿/侦察,因为: 最终类或匿名类

从这个:log = spy(log);

用这个代替:

log = mock(Logger.class);

这样就有用了。

我猜“默认”记录器适配器是final类的一个实例,所以我不能“侦察”它,但我可以模拟整个事情。去图…

这可能意味着你可以用其他一些“非最终”实例来代替它,如果你有的话。或者简化版本等等。就其价值而言……

在某些情况下可能适用的另一种解决方法是创建一个由最终类实现的接口,更改代码以使用该接口而不是具体类,然后模拟该接口。这样可以将契约(接口)与实现(最终类)分离。当然,如果您真正想要的是绑定到最终的类,这将不适用。

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

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

你不能用Mockito模拟最后一个类,因为你自己不能这样做。

我所做的是创建一个非final类来包装final类并作为委托使用。一个例子是TwitterFactory类,这是我的mockable类:

public class TwitterFactory {

    private final twitter4j.TwitterFactory factory;

    public TwitterFactory() {
        factory = new twitter4j.TwitterFactory();
    }

    public Twitter getInstance(User user) {
        return factory.getInstance(accessToken(user));
    }

    private AccessToken accessToken(User user) {
        return new AccessToken(user.getAccessToken(), user.getAccessTokenSecret());
    }

    public Twitter getInstance() {
        return factory.getInstance();
    }
}

缺点是有很多样板代码;好处是您可以添加一些可能与您的应用程序业务相关的方法(如在上面的例子中,getInstance接受用户而不是accessToken)。

在你的例子中,我会创建一个非最终的RainOnTrees类,它委托给最终的类。或者,如果你能让它变成非最终结果,那就更好了。

如果您试图在test文件夹下运行unit-test,那么顶部的解决方案是可以的。只要跟着它添加一个扩展。

但如果你想运行与android相关的类,如context或activity,在androidtest文件夹下,答案是你。