NoClassDefFoundError for MockitoInvocationHandler class - java

I am using mockito-all-1.9.5-rc1.jar and powermock-mockito-1.4.12-full.jar.
When I run this simple unit test for mocking final method in non-final class.
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(ABC.class)
public class ABCTest {
#Test
public void finalCouldBeMock() {
final ABC abc = PowerMockito.mock(ABC.class);
PowerMockito.when(abc.myMethod()).thenReturn("toto");
assertEquals("toto", abc.myMethod());
}
}
When I ran it, I got
java.lang.NoClassDefFoundError: org/mockito/internal/MockitoInvocationHandler
Caused by: java.lang.ClassNotFoundException: org.mockito.internal.MockitoInvocationHandler
When I search fo class MockitoInvocationHandler in mockito-all-1.9.5-rc1.jar and powermock-mockito-1.4.12-full.jar. I couldn't find any.
Need help with this issue! Thank you

Mockito 1.9.5-rc1 had to be refactored internally to allow third party mock maker. MockitoInvocationHandler was part of the Mockito's internals (as the package name suggests) up to Mockito 1.9.0.
Due to these changes, current some older version Powermock releases as of today are not compatible with the latest Mockito release.
Another reason to avoid mocking/stubbing finals or statics ;)
Hope that helps
Cheers,

Related

How to resolve the following import?

Just add some Junit4 test cases,
import static org.junit.Assert.*;
but it prompts some errors until I changed to
#org.junit.Test from #Test
What should I do if I would like to just use #Test?
You need to also
import org.junit.Test;
Test is not part of org.junit.Assert. It is rather part of org.junit.
So it should suffice to do:
import org.junit.Test;
#Test is an annotation class, and you need to import it as such. Including the package, it's name is org.junit.Test
Thus, you need to add this to your imports:
import org.junit.Test;
If there is #Test annotations defined in the code from testng i.e. org.testng.annotations.Test package then the for defining #Test annotation of junit you will have to write #org.junit.Test unless you delete the import statement of the testng package org.testng.annotations.Test

Display a user-friendly message when JUnit tests fails

I got the message like this.
com.controller.Test1 > test FAILED
java.lang.NoSuchMethodError at Test1.java:18
The dependencies for test compiling is
testCompile "junit:junit:4.11",
'org.mockito:mockito-all:1.10.19',
'com.jayway.jsonpath:json-path:2.2.0',
'org.hamcrest:hamcrest-all:1.3',
'org.flywaydb.flyway-test-extensions:flyway-dbunit-spring4-test:4.0'
And this is my test code.
package com.controller;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThat;
#RunWith(MockitoJUnitRunner.class)
public class Test1 {
#Test
public void test(){
assertThat(Long.valueOf(1), instanceOf(Integer.class));
}
}
I want the message like this.
Expected: an instance of java.lang.Integer
but: <1L> is a java.lang.Long
The java.lang.NoSuchMethodError is not related to JUnit specifically. Instead, it indicates that the version of a class that was on your compiler's classpath is different from the version of the class that is on your runtime classpath.
The reason for the clash is that JUnit comes with its own org.hamcrest.Matcher class that is being used instead of the one imported in your code. Use mockito-core in your imports instead of mockito-all to exclude the matcher.

PowerMock class not found

For some reason I fail to follow a pretty straight forward PowerMock example.
I included powermock-mockito-1.5.1-full in my classpath, and I try to test a public final method (following this example).
For some reason I am not able to make the import to the PowerMock class.
import org.junit.*;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.cleancode.lifesaver.camera.*;
#RunWith(PowerMockRunner.class)
#PrepareForTest(android.hardware.Camera.class)
public class CameraTests {
private android.hardware.Camera _cameraMock;
#Before
public void setUp() {
_cameraMock = PowerMockito.mock(android.hardware.Camera.class);
}
#Test
public void releaseCamera() {
ICamera camera = new Camera(_cameraMock);
// Compile error: PowerMock can't be resolved
PowerMock.replay(_cameraMock);
// I also tried PowerMockito.replay(_cameraMock) but that also doesn't exist.
camera.release();
Mockito.verify(_cameraMock).release();
}
}
As the comment explains, the PowerMock class can't be imported from the power mock jar.
It feels like a silly question, but I really can't find anything on the internet.
Where should I be able to find the static class PowerMock? I also used Java Decompile to search the powermock library, no hits on powermock / replay.
The example you are following PowerMock.replay(_cameraMock); is using EasyMock, while you seem to be wanting Mockito. Take a look at this tutorial for mockito & power mock
I suggest you not to create your mock in your setUp() (Before) method, because a mock is very complicated, for example you can tell it exactly how many time it should expect a method is called, if you declare a "general" mock for all your tests it's very difficult to control this behaviour.
maybe (without the code I can only guess) you want that your android.hardware.Camera is called inside your Camera.release() method, am I right? so I whould do like this:
The method you are trying to mock is not static, it's a normal final method. You can try to do this:
android.hardware.Camera mock = PowerMock.createMock(android.hardware.Camera.class);
PowerMock.expect(mock.release());
PowerMock.replay();
ICamera camera = new Camera(mock);
camera.release();
PowerMock.verify(mock);
if inside camera.relase() is not called exactly once the android.hardware.Camera.release() method the test fails.

Why does a call to fail() compile in a Java Class using JUnit

This seems like it shouldn't compile and run as Object does not have a fail() method. At compile time is something funky happening? (I am using NetBeans):
import static org.junit.Assert.*;
import org.junit.Test;
public class Test {
#Test
public void hello() {
fail();
}
}
Regards,
Guido
Your import static line imports all static members of the Assert class into the static namespace of your compilation unit. The fail() call refers to Assert.fail().
The confusion you are experiencing regarding where fail() is defined is precisely why I don't usually recommend using import static. In my own code, I usually import the class and use it to invoke the static methods:
import org.junit.Assert;
import org.junit.Test;
public class Test {
#Test
public void hello() {
Assert.fail();
}
}
Much more readable.
However, as JB Nizet points out, it is fairly common practice to use import static for JUnit's assertions; when you write and read enough JUnit tests, knowing where the assertion methods come from will become second nature.
This is perfectly correct and it will run and compile - I already checked using eclipse.
The reason is the static import:
import static org.junit.Assert.*;
that adds all the static fields or methods from the org.junit.Assert class - hence including fail() method.
Nevertheless a problem that might occur is the fact that the name of your test class is the same as the name of the annotation
#Test
hence it will generate an error:
The import org.junit.Test conflicts with a type defined in the same file
This error is coming because your classname and annotation name are same(Test).Change your class name to 'Test1' or other than Test.

Finding import static statements for Mockito constructs

I'm trying to crash through the brick wall between me and Mockito. I've torn my hair out over trying to get correct import static statements for Mockito stuff. You'd think someone would just throw up a table saying that anyInt() comes from org.mockito.Matchers and when() comes from org.mockito.Mockito, etc., but that would be too helpful to newcomers, no?
This sort of thing, especially when mixed in with myriad more import statements ending in asterisks, isn't always very helpful:
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
Yes, I know about and have been trying to use the Eclipse Window -> Preferences-> Java -> Editor-> Content Assist -> Favorites mechanism. It helps, but it doesn't hit the nail on the head.
Any answers to this question would be appreciated.
Many thanks,
Russ
Here's what I've been doing to cope with the situation.
I use global imports on a new test class.
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.mockito.Matchers.*;
When you are finished writing your test and need to commit, you just CTRL+SHIFT+O to organize the packages. For example, you may just be left with:
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Matchers.anyString;
This allows you to code away without getting 'stuck' trying to find the correct package to import.
The problem is that static imports from Hamcrest and Mockito have similar names, but return Matchers and real values, respectively.
One work-around is to simply copy the Hamcrest and/or Mockito classes and delete/rename the static functions so they are easier to remember and less show up in the auto complete. That's what I did.
Also, when using mocks, I try to avoid assertThat in favor other other assertions and verify, e.g.
assertEquals(1, 1);
verify(someMock).someMethod(eq(1));
instead of
assertThat(1, equalTo(1));
verify(someMock).someMethod(eq(1));
If you remove the classes from your Favorites in Eclipse, and type out the long name e.g. org.hamcrest.Matchers.equalTo and do CTRL+SHIFT+M to 'Add Import' then autocomplete will only show you Hamcrest matchers, not any Mockito matchers. And you can do this the other way so long as you don't mix matchers.
For is()
import static org.hamcrest.CoreMatchers.*;
For assertThat()
import static org.junit.Assert.*;
For when() and verify()
import static org.mockito.Mockito.*;
My imports
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.Test;
And it works
import static org.mockito.Matchers.anyInt;
e.g.
when(listMock.get(anyInt())).thenReturn("stackoverflow");

Categories

Resources