java - Mockito 模拟一个具有不相关静态方法的类

标签 java android unit-testing mockito

我想用 Mockito 模拟一个具有一些不相关静态方法的类的对象。

这里有很多关于堆栈溢出的问题,这些问题解释了 Mockito 不可能模拟静态方法。但是,我在单元测试中需要的对象的静态方法与测试无关。

更具体地说,我想为一种在缓存中查找文档的方法编写单元测试,并在缓存未命中的情况下从 Couchbase lite 数据库加载它们。不幸的是 com.couchbase.lite.Document 类有一些静态方法并试图模拟它们

Document mockDocument = Mockito.mock(Document.class);

导致 java.lang.UnsatisfiedLinkError。 我打算模拟一些非静态方法,例如

doReturn("SomeString").when(mockDocument).getString("someKey");

但是静态方法从未使用过,无论是在测试方法中还是在单元测试本身中。 关于 Couchbase,我想这个库与我的问题并不是特别相关,只是我想模拟某个库类的对象,它包含不相关的静态方法和相关的非静态方法。

更新: 这是堆栈跟踪

java.lang.UnsatisfiedLinkError: com.couchbase.lite.internal.core.C4Log.setLevel(Ljava/lang/String;I)V

at com.couchbase.lite.internal.core.C4Log.setLevel(Native Method)
at com.couchbase.lite.FileLogger.setupDomainObjects(FileLogger.java:84)
at com.couchbase.lite.FileLogger.<init>(FileLogger.java:47)
at com.couchbase.lite.Log.<init>(Log.java:35)
at com.couchbase.lite.AbstractDatabase.<clinit>(AbstractDatabase.java:80)
at com.couchbase.lite.internal.support.Log.sendToLoggers(Log.java:401)
at com.couchbase.lite.internal.support.Log.e(Log.java:247)
at com.couchbase.lite.NativeLibraryLoader.load(NativeLibraryLoader.java:41)
at com.couchbase.lite.Document.<clinit>(Document.java:42)
at sun.reflect.GeneratedSerializationConstructorAccessor10.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:19)
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:47)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:25)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:63)
at org.mockito.Mockito.mock(Mockito.java:1910)
at org.mockito.Mockito.mock(Mockito.java:1819)
at com.my.app.ClassOfTheTest.nameOfTheTest(ClassOfTheTest.java:1234)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)

最佳答案

为这些静态方法创建一个 DocumentUtils 类,这样如果您想在 UnitTest 中使用这些方法,您仍然可以这样做而无需模拟它。

DocumentUtils.someMethod(args);

更新:

DocumentUtils 类可能看起来像(添加了一些可能与您的用例无关的假想静态方法):

public final class DocumentUtils {

public static boolean isDocumentReadable(Document doc) {
    ...
}

public static boolean isDocumentWrittenInEnglish(Document doc) {
    ...
}

public static List<Document> getEnglishWrittenDocuments(List<Document> docs) {
    ...
}

public static boolean areDocumentsTheSame(Document doc1, Document doc2) {
    ...
}

}

测试:

当涉及到测试时,您甚至可能根本不需要引用此类...

但是,您需要确保将以某种方式传递给这些方法的模拟 Document 对象将返回预期值。

例如,如果要在某个阶段调用 DocumentUtils.isDocumentWrittenInEnglish(Document doc),则必须预先设置模拟以返回预期值:

when(mockedDocument.getLanguage()).thenReturn(LANGUAGE_ENGLISH);

关于java - Mockito 模拟一个具有不相关静态方法的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59840298/

相关文章:

java - BroadcastReceiver - 如何在每次用户打开/关闭屏幕时触发服务

java - Eclipse ANT Build.xml 创建 JAR 显示损坏的文件

java - 从与类路径不同的位置加载 spring XML

java - 如何在第二个 JSF 项目中运行一个 JSF WAR 文件?

c# - 无法使用 JustMock 模拟简单对象数组

android - 如何根据所选语言从右到左而不是从左到右定位标签?

java - 主机未解析 : api. twitter.com:80

java - 在Android设备中使用GCC工具链

android - 使用 Kotlin Coroutines 和 Flow 测试 Room DAO 的方法

java - ResultSet 关闭后不允许执行 SQLException 操作