Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Mockito mock具有无关静态方法的类_Java_Android_Unit Testing_Mockito - Fatal编程技术网

Java Mockito mock具有无关静态方法的类

Java Mockito mock具有无关静态方法的类,java,android,unit-testing,mockito,Java,Android,Unit Testing,Mockito,我想用Mockito来模拟一个对象,这个类有一些不相关的静态方法 这里有很多关于堆栈溢出的问题,可以解释Mockito不可能模拟静态方法。但是,我在单元测试中需要的对象的静态方法与测试无关 更具体地说,我想为一个方法编写一个单元测试,该方法在缓存中查找文档,并在缓存未命中的情况下从Couchbase lite数据库加载文档。不幸的是,com.couchbase.lite.Document类有一些静态方法并试图模拟它们 Document mockDocument = Mockito.mock(Do

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

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

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

Document mockDocument = Mockito.mock(Document.class);
导致
java.lang.UnsatifiedLinkError
。 我打算模拟一些非静态方法,例如

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)
java.lang.UnsatisfiedLinkError:com.couchbase.lite.internal.core.C4Log.setLevel(Ljava/lang/String;I)V
位于com.couchbase.lite.internal.core.C4Log.setLevel(本机方法)
位于com.couchbase.lite.FileLogger.setupDomainObjects(FileLogger.java:84)
位于com.couchbase.lite.FileLogger(FileLogger.java:47)
在com.couchbase.lite.Log.(Log.java:35)
位于com.couchbase.lite.AbstractDatabase。(AbstractDatabase.java:80)
位于com.couchbase.lite.internal.support.Log.sendToLoggers(Log.java:401)
位于com.couchbase.lite.internal.support.Log.e(Log.java:247)
位于com.couchbase.lite.NativeLibraryLoader.load(NativeLibraryLoader.java:41)
位于com.couchbase.lite.Document(Document.java:42)
位于sun.reflect.GeneratedSerializationConstructorAccessor10.newInstance(未知源)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:423)
位于org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
位于org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
位于org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:19)
位于org.mockito.internal.creation.bytebuddy.Subclass ByteBuddyMockMaker.createMock(Subclass ByteBuddyMockMaker.java:47)
位于org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:25)
位于org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
位于org.mockito.internal.MockitoCore.mock(MockitoCore.java:63)
位于org.mockito.mockito.mock(mockito.java:1910)
位于org.mockito.mockito.mock(mockito.java:1819)
位于com.my.app.classoftest.nameoftest(classoftest.java:1234)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:498)
位于org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:50)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
位于org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:47)
位于org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
位于org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
位于org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
位于org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
位于org.junit.rules.RunRules.evaluate(RunRules.java:20)

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

DocumentUtils.someMethod(args);
更新:

DocumentUtils类的外观(添加了一些可能与您的用例无关的虚构静态方法):


utils类不会扩展文档,它的目的是能够完成可重用逻辑并返回答案,而不需要传递的对象以外的任何其他依赖项。我已经更新了我的答案。谢谢你的澄清!因此,基本上您建议将静态方法移动到单独的类(即DocumentUtils),以便定期模拟剩余的非静态对象,对吗?我现在的问题是,我想要模拟的“Document”对象来自一个库(即Couchbase lite),而静态方法是在这个库中实现的。因此,拆分类并不像我自己编写类那样容易。然后我建议创建一个DocumentWrapper类来解决这个问题。这意味着包装器类必须在生产代码中使用,而不是在原始文档类中使用?因此,使用包装器而不是直接访问将是提高可测试性的牺牲,对吗?正确。包装是一种解决方案,另一种可能是使用PowerMock,但是,我以前没有使用过它,因此无法提供更多信息,似乎有很多工作需要使用正确的体系结构来解决,但是在您的场景中可能值得一看。。。你能添加完整的stacktrace吗?我怀疑mockito未能模拟该类的原因在这里有提及。@第二次我更新了我的答案,从我对堆栈溢出的搜索中,我假设问题是
couchbase.lite.Document
s使用了Mockito无法模拟的静态方法。我用
couchbase-lite-java-core
1.4.4
尝试了这个方法,但没有得到这个错误。但是我注意到我试图模拟的
文档
类没有
getString(…)
方法,因此您可能使用了不同的版本。
unstatistifiedlinkerror
通常表示类路径中缺少某个jar。我使用的是Couchbase lite 2.6版,我可以模拟Couchbase
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) {
    ...
}

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