java.lang.NoClassDefFoundError: org/objenesis/Obje

2019-04-19 11:34发布

问题:

I don't know why I have that error with mockito

java.lang.NoClassDefFoundError: org/objenesis/ObjenesisStd
at org.mockito.internal.creation.jmock.ClassImposterizer.<init>(ClassImposterizer.java:36)
at org.mockito.internal.creation.jmock.ClassImposterizer.<clinit>(ClassImposterizer.java:29)
at org.mockito.internal.util.MockCreationValidator.isTypeMockable(MockCreationValidator.java:17)
at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:21)
at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:133)
at org.mockito.internal.creation.MockSettingsImpl.confirm(MockSettingsImpl.java:127)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:50)
at org.mockito.Mockito.mock(Mockito.java:1243)
at org.mockito.Mockito.mock(Mockito.java:1120)
at fr.oap.SubscriptionTest.testGetSubscriptionById(SubscriptionFactoryTest.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: org.objenesis.ObjenesisStd
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 29 more

About my class of Test is like this :

import junit.framework.TestCase;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import fr.aop.subscription.AbstractSubscription;
public class SubscriptionTest extends TestCase {
@Test
public void testGetSubscriptionById() {
    ArgumentCaptor<AbstractSubscription> 
arg=ArgumentCaptor.forClass(AbstractSubscription.class);        
     Subscription objMock=Mockito.mock(Subscription.class);        
    Mockito.when(objMock.getSubscribById(1)).thenReturn(arg.getValue());
}
}

And about the method getSubscribById whitch is in the class Subscription:

@Override
public AbstractSubscription getSubscriptionById(final Integer id) {
    this.log.debug("BEGIN: getSubscriptionById id = " + id);
    AbstractSubscription obj = null;
    if (id != null) {
        final StringBuilder queryString = new StringBuilder("select c from AbstractSubscription c ");

        try {
            queryString.append("where c.id = :id");
            Query query = this.getEntityManager().createQuery(queryString.toString());
            query = query.setParameter("id", id);
            obj = (AbstractSubscription) query.getSingleResult();
        } catch (final Exception exc) {

        }
    }
    return obj;
}

when I instanciate the Subcription class it demand me the connection to the database, that's why I want to escape this and looking for a solution like mockito

回答1:

ClassNotFoundException is result of a class loader that is not able to load a particular class.

In your case Mockito has a transitive dependency to Objenesis (it needs Objenesis for correct behavior). You are most likely trying to execute your test with Mockito on test class path, but without Objenesis.

You need to add Objenesis to your test class path.

For maven projects, be sure that:

  1. you have declared Mockito as test dependency

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>1.10.19</version>
        <scope>test</scope>
    </dependency>
    
  2. to run a particular test from the command line execute

    mvn test -Dtest=fullyQualifedNameToYourTestClass
    


回答2:

You can try adding the mockito-all artifact instead of mockito-core, it works since version 1.9.5



回答3:

I was getting the same error of:

java.lang.NoClassDefFoundError: org/objenesis/ObjenesisStd

when I was running a test in a new project that was using Mockito.

Turns out in addition to adding the Mockito Dependencies I also had to add the Objenesis dependency. All I need to do was add the below dependency to my pom.xml and it all worked perfectly fine.

<dependency>
    <groupId>org.objenesis</groupId>
    <artifactId>objenesis</artifactId>
    <version>2.3</version>
    <scope>test</scope>
</dependency>


回答4:

I have this issue with the version of mockito-core 2.22.0.

After investigation it seems that the jar of objenesis was corrupted in my maven repository...

Just a rm -rf .m2/repository/org/objenesis is enough



回答5:

I had a similar problem in an Android project using gradle.

Like @Popeye did for maven, I added the following line to build.gradle, among dependencies:

testImplementation 'org.objenesis:objenesis:2.3'

That solved my problem.