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

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


当前回答

我克服了这条信息:

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

从这个:log = spy(log);

用这个代替:

log = mock(Logger.class);

这样就有用了。

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

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

其他回答

如果你需要在Android的测试中使用Mockito(即在Android设备中运行),你不能使用Mockito -inline。有一个特殊的模拟android版本也没有解决“最终类”的问题。唯一可行的解决方案似乎是Dexmaker库。唯一的限制是它只能在Android P (Android 9, API 28)或更高版本上运行。导入方式如下:

androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito-inline:2.28.1"

注意,还有一个“dexmaker-mockito”版本,它也不适用于final类。确保您导入了“dexmaker-mockito-inline”。

我来跟进一下。请将这一行添加到您的gradle文件:

testCompile group: 'org.mockito', name: 'mockito-inline', version: '2.8.9'

我尝试了不同版本的mockito-core和mockito-all。他们都不工作。

使用Powermock。这个链接展示了如何做到这一点:https://github.com/jayway/powermock/wiki/MockFinal

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

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

由RC和Luigi R. Viggiano共同提供的解决方案可能是最好的主意。

尽管Mockito在设计上不能模拟final类,但是委托方法是可能的。这有它的优点:

如果API一开始就打算将类改为非final类(final类有其好处),那么不必强制将类改为非final类。 您正在测试API周围装饰的可能性。

在您的测试用例中,您故意将调用转发到被测试的系统。因此,通过设计,你的装饰什么都不做。

因此,测试还可以证明用户只能修饰API,而不能扩展API。

从更主观的角度来看: 我更喜欢将框架保持在最低限度,这就是为什么JUnit和Mockito通常对我来说就足够了。事实上,以这种方式限制有时也会迫使我进行重构。