【发布时间】:2020-01-21 11:35:54
【问题描述】:
我想用具有一些不相关静态方法的类的 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)
【问题讨论】:
-
你能添加完整的堆栈跟踪吗?我怀疑其中提到了 mockito 未能模拟该类的原因。
-
@second 我更新了我的答案,从我对堆栈溢出的搜索中我认为问题是
couchbase.lite.Documents 使用了 Mockito 无法模拟的静态方法。 -
我用
couchbase-lite-java-core1.4.4试过这个,但没有收到这个错误。但我注意到我尝试模拟的Document类没有getString(...)方法,因此您可能使用的是不同的版本。UnstatisfiedLinkError通常表示类路径中缺少某些 jar。 -
我使用的是 Couchbase lite 版本 2.6,我也可以使用旧的 Couchbase lite 版本 (1.4.x) 模拟 couchbase.lite.Document 类,但是新版本 2.x+ 引入了问题.如果我的具体问题不是源于不可修改的静态方法(与我在问题中提出的相反),我很乐意为此找到解决方案,即使这将是另一个问题的答案。
-
mvn 存储库没有 2.6er 版本的 jar,所以我无法验证这一点。但是2.7er community version 没有问题。关于你的问题:我不太明白你想用这些静态方法做什么,因为你提到你从不使用它们。对于一个类的模拟,是否有静态方法应该是无关紧要的。
标签: java android unit-testing mockito