I haven't touched Mockito for a while, and I have never used it extensively. But today in some new code I wanted to use best practices so I pulled out mockito-core 2.0.54-beta using the following Java version:
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
I needed an instance of this interface for testing:
https://bitbucket.org/globalmentor/rincl/src/bf0e8875a1bae16247dd904e0b8bc067c9f8abc9/src/main/java/io/rincl/ResourceI18nConcern.java
public interface ResourceI18nConcern extends Concern {
public Locale getLocale(#Nonnull Locale.Category category);
public void setLocale(#Nonnull Locale.Category category, #Nonnull Locale locale);
public default void setLocale(#Nonnull Locale locale) {...}
public Resources getResources(#Nonnull final Class<?> contextClass) throws ResourceConfigurationException;
}
That interface extends this one (just an empty marker interface):
https://bitbucket.org/globalmentor/csar/src/125b837e9936ddb8d6340fa99b6b5da872d1e6e5/src/main/java/io/csar/Concern.java
In my test I tried to do this simple thing:
final ResourceI18nConcern defaultConcern=mock(ResourceI18nConcern.class);
I get the following stack trace:
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: interface io.rincl.ResourceI18nConcern
Mockito can only mock visible & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
Underlying exception : java.lang.IllegalArgumentException: object is not an instance of declaring class
at io.rincl.RinclTest.defaultConcernRinclGetLocaleIsConcernLocale(RinclTest.java:91)
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:483)
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.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
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:483)
at net.bytebuddy.description.type.TypeDescription$Generic$AnnotationReader$ForTypeArgument.resolve(TypeDescription.java:3875)
at net.bytebuddy.description.type.TypeDescription$Generic$AnnotationReader$Delegator$Chained.resolve(TypeDescription.java:3501)
at net.bytebuddy.description.type.TypeDescription$Generic$AnnotationReader$ForTypeArgument.resolve(TypeDescription.java:3834)
at net.bytebuddy.description.type.TypeDescription$Generic$AnnotationReader$Delegator.asList(TypeDescription.java:3477)
at net.bytebuddy.description.type.TypeDescription$Generic$OfWildcardType$ForLoadedType.getDeclaredAnnotations(TypeDescription.java:4771)
at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$TypeVariableErasing.onWildcard(TypeDescription.java:676)
at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$TypeVariableErasing.onWildcard(TypeDescription.java:659)
at net.bytebuddy.description.type.TypeDescription$Generic$OfWildcardType.accept(TypeDescription.java:4679)
at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$TypeVariableErasing.onParameterizedType(TypeDescription.java:687)
at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$TypeVariableErasing.onParameterizedType(TypeDescription.java:659)
at net.bytebuddy.description.type.TypeDescription$Generic$OfParameterizedType.accept(TypeDescription.java:5021)
at net.bytebuddy.description.type.TypeDescription$Generic$LazyProjection.accept(TypeDescription.java:5794)
at net.bytebuddy.description.method.ParameterDescription$TypeSubstituting.getType(ParameterDescription.java:866)
at net.bytebuddy.description.method.ParameterList$AbstractBase.asTypeList(ParameterList.java:85)
at net.bytebuddy.description.method.MethodDescription$AbstractBase.asTypeToken(MethodDescription.java:635)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default$Key$Harmonized.of(MethodGraph.java:862)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default$Key$Store.registerTopLevel(MethodGraph.java:1059)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:569)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.analyze(MethodGraph.java:529)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:565)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.compile(MethodGraph.java:502)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$AbstractBase.compile(MethodGraph.java:423)
at net.bytebuddy.dynamic.scaffold.MethodRegistry$Default.prepare(MethodRegistry.java:489)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:153)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2564)
at org.mockito.internal.creation.bytebuddy.MockBytecodeGenerator.generateMockClass(MockBytecodeGenerator.java:60)
at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.generate(CachingMockBytecodeGenerator.java:72)
at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.getOrGenerateMockClass(CachingMockBytecodeGenerator.java:64)
at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator.get(CachingMockBytecodeGenerator.java:27)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createProxyClass(ByteBuddyMockMaker.java:54)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:27)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:32)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:54)
at org.mockito.Mockito.mock(Mockito.java:1443)
at org.mockito.Mockito.mock(Mockito.java:1356)
... 26 more
Am I doing something wrong? This seemed to me as if it should be straightforward.
To reproduce this problem, clone https://bitbucket.org/globalmentor/rincl.git and check out commit 2f88d7c5e5ac17b6d316ed54c12cb7b447b7d6ac. Then try to run the following test:
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.*;
import java.util.Locale;
import java.util.Locale.Category;
import org.junit.*;
public class RinclTest {
#Test
public void defaultConcernRinclGetLocaleIsConcernLocale() {
final ResourceI18nConcern defaultConcern=mock(ResourceI18nConcern.class);
}
}
Your Java runtime version is from March 2014; plenty of bugs have been fixed in the VM ever since and you should really upgrade. I am 99% sure that this problem is related to type annotations (#NonNull) which were introduced in this version for the first time in this exact release. I am sure that your problem will go away if you upgrade your VM.
I can successfully execute your proposed test with a recent build of the HotSpot VM.
Had the same issue with my project and used the Rincl project above to confirm I was having the same issue. Using JDK 1.8.0_11 on Mac the reported errors were the same as Garret. Updating to version JDK 1.8.0_181 I ran the Rincl test with NO errors. Apparently Mockito is using the latest of the JDK 1.8.0.
If this is helpful to anyone, I got the same above issue and tried all other options like upgrading the JVM etc, but what solved my issue is :
https://github.com/mockito/mockito/issues/1606
By and large reverting my mockito version to 2.23.+ solved the issue for me.
Related
I have a class ClassA which is extending DispatchAction class from org.apache.struts.actions.DispatchAction, I have written JUnit code coverage test for ClassA but whenever I try to run the test case I keep getting these error but if I remove the extends DispatchAction from ClassA the test runs normally without any error but then obviously my application won't work
ClassA
public class ClassA extends DispatchAction {
//some methods and other code
}
TestClassA
#RunWith(Junit4.class)
public class TestClassA {
#InjectMocks
ClassA objA;
/* mock some objects here */
#Before
public void setUp()
{
MockitoAnnotations.openMocks(this);
}
#Test
public void methodToTest()
{
//Coverage code
objA.methodA();
}
}
Here is the stack trace I get when I run this test case (when I keep "extends DispatchAction" in class ClassA )
java.lang.ExceptionInInitializerError at
java.lang.J9VMInternals.ensureError(J9VMInternals.java:148) at
java.lang.J9VMInternals.recordInitializationFailure(J9VMInternals.java:137) at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:83) at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:57) at
java.lang.reflect.Constructor.newInstance(Constructor.java:437) at
org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217) at
org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at
org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263) at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at
org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at
org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: java.lang.NullPointerException at
org.apache.struts.util.MessageResources.getMessageResources(MessageResources.java:577) at
org.apache.struts.actions.DispatchAction.<clinit>(DispatchAction.java:153) ... 22 more
Now if I remove the "extends DispatchAction" from class ClassA it will run and cover the intended lines in the test case without any problems but my application won't work as intended.
I tried searching on how to resolve all those errors but I cannot find anything that might help.
Resolved the issue by adding the latest j2ee jar which was missing earlier.
I'm using Room on Android. So I've got my data model class with the proper Room annotations and a single public constructor. It uses a builder pattern and tries to be immutable. It's here.
Then I've got my #Dao-annotated interface with #Query, #Update, and #Insert annotations next to all the method declarations as it should be. Right over here.
Finally, I've got my Dao test class, which uses Room.inMemoryDatabaseBuilder. It is here.
So when I run the tests in GoalsDaoTest, they all pass except for two: One that uses the Dao method annotated #Update, and another whose Dao method uses an SQL UPDATE command inside its #Query.
Here's my test set-up and tear-down, using Room.inMemoryDatabaseBuilder:
#Before
public void initDb() {
mDatabase = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getContext(),
SelfCareDatabase.class).build();
}
#After
public void closeDb() {
mDatabase.close();
}
Here's the first failing test:
#Test
public void updateArchivedAndGetById() {
// When inserting a goal
mDatabase.goalDao().insertGoal(GOAL);
// When the goal is updated
mDatabase.goalDao().updateArchived(GOAL.getId(), true);
// When getting the goal by id from the database
Goal loaded = mDatabase.goalDao().getGoalById(ID);
// The loaded data contains the expected values
assertGoal(loaded, GOAL.getId(), GOAL.getTitle(), GOAL.getInterval(), GOAL.getPolarity(), true, GOAL.getTouched());
}
Here's the error it produces when I run it:
java.lang.NoSuchMethodError: No interface method updateArchived(Ljava/lang/String;Z)V in class Lcom/beatboxchad/android/selfcaredashboard/data/source/local/GoalsDao; or its super classes (declaration of 'com.beatboxchad.android.selfcaredashboard.data.source.local.GoalsDao' appears in /data/app/com.beatboxchad.android.selfcaredashboard-1/base.apk)
at com.beatboxchad.android.selfcaredashboard.data.source.local.GoalsDaoTest.updateArchivedAndGetById(GoalsDaoTest.java:155)
at java.lang.reflect.Method.invoke(Native Method)
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 android.support.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
at android.support.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:58)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:375)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1939)
And yet, that method is properly declared and annotated in the GoalsDao class:
/**
* Update the Archived status of a goal
*
* #param goalId id of the goal
* #param archived status to be updated
*/
#Query("UPDATE goals SET archived = :archived WHERE entryid = :goalId")
void updateArchived(String goalId, boolean archived);
Here's the other test:
#Test
public void updateGoalAndGetById() {
// When inserting a goal
mDatabase.goalDao().insertGoal(GOAL);
// When the goal is updated
Goal updatedGoal = new Goal.Builder(ID)
.setTitle(TITLE2)
.setPolarity(POLARITY2)
.setInterval(INTERVAL2)
.setArchived(ARCHIVED2)
.setTouched(TOUCHED2)
.build();
mDatabase.goalDao().updateGoal(updatedGoal);
// When getting the goal by id from the database
Goal loaded = mDatabase.goalDao().getGoalById(ID);
// The loaded data contains the expected values
assertGoal(loaded, ID, TITLE2, INTERVAL2, POLARITY2, ARCHIVED2, TOUCHED2);
}
Here's its error:
java.lang.NoSuchMethodError: No interface method updateGoal(Lcom/beatboxchad/android/selfcaredashboard/data/Goal;)I in class Lcom/beatboxchad/android/selfcaredashboard/data/source/local/GoalsDao; or its super classes (declaration of 'com.beatboxchad.android.selfcaredashboard.data.source.local.GoalsDao' appears in /data/app/com.beatboxchad.android.selfcaredashboard-1/base.apk)
at com.beatboxchad.android.selfcaredashboard.data.source.local.GoalsDaoTest.updateGoalAndGetById(GoalsDaoTest.java:140)
at java.lang.reflect.Method.invoke(Native Method)
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 android.support.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
at android.support.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:58)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:375)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1939)
And yet! Confound me! What madness causes the computer to lie? GoalsDao.java excerpt:
/**
* Update a goal.
*
* #param goal goal to be updated
* #return the number of goals updated. This should always be 1.
*/
#Update
int updateGoal(Goal goal);
I've exhausted all the low-hanging fruit on this one. Everything appears to conform to the docs (though I'm suspicious of my immutable builder'd Goal class), and I've attempted to follow advice given in the following places:
Why Room entities don't work with immutable properties in Android
Espresso Test Failing: No interface method trackUsage() in UsageTracker.java
Room Persistence Library run time exception when calling Rooms inMemoryBuilder method
But I'm not using Kotlin nor the #Relation annotation, and even when I played with all kinds of different versions in my build.gradle files, it stayed broken. The bright side is, I've learned a lot about that boring part. tl;dr I'm stumped.
Just in case it's helpful context, my app is strongly based on the todo‑mvvm‑databinding example from https://github.com/googlesamples/android-architecture. I mention this because everything works in the sample, but I've added some complexity and perhaps made a mistake along the way that somebody more experienced will recognize. Particularly, I've mangled that #Entity Goal class (Task in the example app), trying to keep it immutable and adding the builder pattern and several attributes. I'm not done mangling it either -- touched is about to be its own table.
I'm also unskilled in troubleshooting whatever turns an interface and a bunch of annotations into code. Any advice about where to look in resolving this is as useful as the answer it'll lead to. I'm new to Android Studio, Java, and the whole build process.
Thank you!
Invalidate caches and restart in android studio helped
I was adding suspend to some functions in the DAO and ran into this. A simple Build\Clean fixed it
This question already has answers here:
How to mock a final class with mockito
(28 answers)
Closed 5 years ago.
I have one class which is final, which has one method on which I want to perform certain action. Because of this I want to create object of final class. But I am unable to create it, following is my class.
public final class A {
private String name;
A(String name){
this.name = name;
}
public String getName(){
return name;
}
}
In my junit test case I want to create object of that class, like below
Class TestA{
#Test
public void testA(){
A a = mock(A.class);
when(a.getName()).then("ABC"); //on this line i am getting exception
}
}
I have tried it by using new keyword also, but not working. So is there anyway to create a mock object of final class?
Following exception I facing,
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class A
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types
at com.rocket.map.resources.TestA.testA(TestA.java:46)
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.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
try using this.
Use the #RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
Use the #PrepareForTest(ClassWithFinal.class) annotation at the class-level of the test case.
Use PowerMock.createMock(ClassWithFinal.class) to create a mock object for all methods of this class (let's call it mockObject).
Use PowerMock.replay(mockObject) to change the mock object to replay mode.
Use PowerMock.verify(mockObject) to change the mock object to verify mode.
Also refer this answer - link
And Tutorial.
Both look easy to implement.
This is not possible with Mockito v1
Please look into this link. I think in advance version or powermockito you can do this.Powermockito example
This question already has answers here:
Android Studio 3.0 Canary 1: Kotlin tests or Java tests referring to Kotlin classes fail
(4 answers)
Closed 5 years ago.
This is the class that I'm trying to call from my unit test
package bj.discogsbrowser.artistreleases
class ArtistResultFactory {
companion object {
#JvmStatic fun buildArtistResult(members: Int): ArtistResult {
val artistResult = ArtistResult()
artistResult.nameVariations = listOf("ye")
artistResult.dataQuality = "really good quality, we have the best qualities"
return artistResult
}
}
}
This is what the test looks like:
#Test
fun setArtistNoMembers_displaysNoMembers() {
controller.setArtist(ArtistResultFactory.buildArtistResult(0))
...
assertEquals(copyOfModels.size, 8)
}
Same test in Java (which also fails):
#Test
public void setArtistNoMembers_displaysNoMembers()
{
controller.setArtist(ArtistResultFactory.buildArtistResult(0));
...
assertEquals(copyOfModels.size(), 8);
}
In both Kotlin and Java I get the stack trace:
java.lang.NoClassDefFoundError: bj/discogsbrowser/artistreleases/ArtistResultFactory
at bj.discogsbrowser.artist.ArtistControllerTest.setArtistNoMembers_displaysNoMembers(ArtistControllerTest.java:70)
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.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:488)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:209)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:109)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:36)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:63)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
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 com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
Caused by: java.lang.ClassNotFoundException: bj.discogsbrowser.artistreleases.ArtistResultFactory
at org.robolectric.internal.bytecode.SandboxClassLoader.getByteCode(SandboxClassLoader.java:161)
at org.robolectric.internal.bytecode.SandboxClassLoader.maybeInstrumentClass(SandboxClassLoader.java:108)
at org.robolectric.internal.bytecode.SandboxClassLoader.findClass(SandboxClassLoader.java:101)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 32 more
I feel it may have something to do with my sourceSets as when I remove those lines then the code won't compile.
sourceSets {
test {
java.srcDirs += "$projectDir/src/testShared"
}
androidTest {
java.srcDirs += "$projectDir/src/testShared"
}
}
ArtistResultFactory is located in /src/testShared/. When it was a Java class, the tests ran fine.
My app build.gradle includes
apply plugin: "kotlin-android"
apply plugin: 'kotlin-android-extensions'
at the top.
You need to make it an "object" instead of "class" in order to access it singleton style in Kotlin.
If you do make it an object (which is the right thing to do with things like a Factory which are typically singletons), then in Java you will I believe have to do a .getINSTANCE() before you can access the method (not sure if you can make it static or not) as I don't believe companion objects are allowed on objects in Kotlin (I might be mistaken on that though).
I use a Hystrix (v. 1.5.6) command in my tested class, and I'm trying to mock it with Mockito (v. 1.10.19).
Recently I've had to add a special behavior if the command failed because of a timeout:
try {
result = command.execute();
} catch (HystrixRuntimeException err) {
if (command.isResponseTimedOut()) {
/** do stuff **/
}
/** do stuff **/;
}
This is the code in my test class :
HttpClientCommand command = mock(HttpClientCommand.class);
when(commandFactory.get(anyString(), anyString(), anyString(), anyMapOf(String.class, String.class))).thenReturn(command);
when(command.execute()).thenThrow(hystrixRuntimeException);
when(command.isResponseTimedOut()).thenReturn(false);
My HttpClientCommand extends the HystrixCommand class. The execute method is in this class, and I have no problem stubbing it.
The HystrixCommand class then extends the AbstractCommand class, where the isResponseTimedOut method is. When I try to stub it, I get a NPE from Mockito (on the when(command.isResponseTimedOut()).thenReturn(false); line, before calling any method on my tested class).
Stack trace :
java.lang.Exception: Unexpected exception, expected<my.custom.exception> but was<java.lang.NullPointerException>
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
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:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.NullPointerException
at com.netflix.hystrix.AbstractCommand.isResponseTimedOut(AbstractCommand.java:1809)
at com.netflix.hystrix.HystrixCommand.isResponseTimedOut(HystrixCommand.java:46)
at com.myClassTest.testGetLocation_shouldThrowCustomException_whenRequestException(myClassTest.java:300)
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:497)
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.ExpectException.evaluate(ExpectException.java:19)
... 22 more
How can I stub this method?
OK the issue is due to a bug with CGLIB, mockito 1.x uses CGLIB. When the method to mock is declared in a non public parent, then CGLIB doesn't intercept the method, hence it executes the real code. The issue is still available on our old issue tracker : issue 212
Two options :
Write a public overload in HttpHystrixCommand that will invoke the super method, but since the abstract command have a lot of methods to handle failure, this is probalby not an option that will scale very well.
Use mockito 2. We have worked with the developer of ByteBuddy – Rafel Winterhalter – to replace CGLIB. ByteBuddy does not have the same shortcomings of CGLIB which was almost abandonned for years. Current version is 2.2.29 and at the time of this anwer regular updates are released.