2012-08-30 14 views
7

ho integrato PowerMock e PowerRule in Junit con MockitoOttenere javassist non trovato con PowerMock e PowerRule in Junit con Mockito

seguenti sono le dipendenze:

<dependency> 
     <groupId>javassist</groupId> 
     <artifactId>javassist</artifactId> 
     <version>3.12.0.GA</version> 
     </dependency> 
<dependency> 
     <groupId>asm</groupId> 
     <artifactId>asm</artifactId> 
     <version>3.3.1</version> 
</dependency> 

<dependency> 
     <groupId>cglib</groupId> 
     <artifactId>cglib</artifactId> 
     <version>2.2.2</version> 
</dependency> 
<dependency> 
     <groupId>org.powermoc</groupId> 
    <artifactId>powermock-module-junit4</artifactId> 
    <version>1.4.12</version> 
    <scope>test</scope> 
    </dependency> 
<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-api-mockito</artifactId> 
    <version>1.4.12</version> 
    <scope>test</scope> 
</dependency> 
<dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-module-junit4-rule</artifactId> 
     <version>1.4.12</version> 
     <scope>test</scope> 
</dependency> 
<dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-classloading-objenesis</artifactId> 
     <version>1.4.12</version> 
     <scope>test</scope> 
</dependency> 

// My test class is: 

public class TestClass extends AbstractShiroTest{ 
    @Rule 
    public PowerMockRule rule = new PowerMockRule(); 
    @Autowired 
    SomeService someService; 
    @Before 

    public void setUp(){ 
    Map<String, Object> newMap = new HashMap<String, Object>(); 
    newMap.put("userTimeZone", "Asia/Calcutta"); 
    Subject subjectUnderTest = mock(Subject.class); 
      when(subjectUnderTest.getPrincipal()).thenReturn(LMPTestConstants.USER_NAME); 
    Session session = mock(Session.class); 
    when(session.getAttribute(LMPCoreConstants.USER_DETAILS_MAP)).thenReturn(newMap); 
    when(subjectUnderTest.getSession(false)).thenReturn(session); 
    setSubject(subjectUnderTest); 
    PowerMockito.mockStatic(CasSessionUtil.class); 
    when(CasSessionUtil.getCarrierId()).thenReturn(1L); 
} 

    @Test 

public void myTestMethod() { 
someService.doSomething(); 
} 
} 

dove doSomething sta chiamando un metodo statico che Ho bisogno di deridere. Ora, quando sto facendo funzionare il mio banco di prova sto ottenendo javassist.NotFoundException: $ Proxy88

completa analisi dello stack:

java.lang.RuntimeException: javassist.NotFoundException: $ Proxy88 a org.powermock .core.classloader.MockClassLoader.loadUnmockedClass (MockClassLoader.java:187) a org.powermock.core.classloader.MockClassLoader.loadModifiedClass (MockClassLoader.java:147) a org.powermock.core.classloader.DeferSupportingClassLoader.loadClass (DeferSupportingClassLoader .java: 67) in java.lang.ClassLoader.loadClass (ClassL oader.java:252) in java.lang.ClassLoader.loadClassInternal (ClassLoader.java:320) in java.lang.Class.forName0 (metodo nativo) in java.lang.Class.forName (Class.java:247) all'indirizzo org.powermock.api.support.ClassLoaderUtil.loadClass (ClassLoaderUtil.java:66) all'indirizzo org.powermock.api.support.ClassLoaderUtil.loadClass (ClassLoaderUtil.java:26) all'indirizzo org.powermock.classloading.DeepCloner .cloneFields (DeepCloner.java:243) a org.powermock.classloading.DeepCloner.performClone (DeepCloner.java:128) a org.powermock.classloading.DeepCloner.cloneFields (DeepCloner.java:248) a org.powermock .classloading.DeepCloner.performClone (DeepCloner.java:128) presso org.powermock.classloading.DeepCloner.clon eFields (DeepCloner.java:248) a org.powermock.classloading.DeepCloner.performClone (DeepCloner.java:128) a org.powermock.classloading.DeepCloner.cloneFields (DeepCloner.java:248) a org.powermock. classloading.DeepCloner.performClone (DeepCloner.java:128) a org.powermock.classloading.DeepCloner.cloneFields (DeepCloner.java:248) a org.powermock.classloading.DeepCloner.performClone (DeepCloner.java:128) a org.powermock.classloading.DeepCloner.cloneFields (DeepCloner.java:248) presso org.powermock.classloading.DeepCloner.performClone (DeepCloner.java:128) presso org.powermock.classloading.DeepCloner.cloneFields (DeepCloner.java: 248) presso org.powermock.classloading.DeepCloner.performClone (DeepCloner.java:128) all'indirizzo org.powermock.classloading.DeepCloner.clone (DeepCloner.java:82) all'indirizzo org.powermock.classloading.DeepCloner.clone (DeepCloner.java:69) all'indirizzo org.powermock.classloading.ClassloaderExecutor.execute (ClassloaderExecutor. java: 89) in org.powermock.classloading.ClassloaderExecutor.execute (ClassloaderExecutor.java:78) in org.powermock.modules.junit4.rule.PowerMockStatement.evaluate (PowerMockRule.java:49) in org.springframework. test.context.junit4.statements.SpringRepeat.evaluate (SpringRepeat.java:72) all'indirizzo org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild (SpringJUnit4ClassRunner.java:231) all'indirizzo org.junit.runners.BlockJUnit4ClassRunner. runChild (BlockJUnit4ClassRunner.java:50) presso org.junit.runn ers.ParentRunner $ 3.run (ParentRunner.java:193) presso org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:52) presso org.junit.runners.ParentRunner.runChildren (ParentRunner.java:191) presso org.junit.runners.ParentRunner.access $ 000 (ParentRunner.java:42) presso org.junit.runners.ParentRunner $ 2.valore (ParentRunner.java:184) all'indirizzo org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate (RunBeforeTestClassCallbacks. java: 61) all'indirizzo org.junit.internal.runners.statements.RunAfters.evaluate (RunAfters.java:31) all'indirizzo org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate (RunAfterTestClassCallbacks.java:71) a org.junit.runners.ParentRunner.run (ParentRunner.java:236) a org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run (SpringJUnit4ClassRunner.java:174) a org.eclipse.jdt.internal. junit4.runner.JUnit4TestReference.run (JUnit4TestReference.java:50) all'indirizzo org.eclipse.jdt.internal. junit.runner.TestExecution.run (TestExecution.java:38) all'indirizzo org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:467) all'indirizzo org.eclipse.jdt.internal.junit. runner.RemoteTestRunner.runTests (RemoteTestRunner.java:683) all'indirizzo org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:390) all'indirizzo org.eclipse.jdt.internal.junit.runner. RemoteTestRunner.main (RemoteTestRunner.java:197) causato da: javassist.NotFoundException: $ Proxy88 a javassist.ClassPool.get (ClassPool.java:436) a org.powermock.core.classloader.MockClassLoader.loadUnmockedClass (MockClassLoader. java: 180) ... 46 altro

Se cambio la dependecy a

<dependency> 
      <groupId>org.powermock</groupId> 
      <artifactId>powermock-classloading-xstream</artifactId> 
      <version>1.4.12</version> 
      <scope>test</scope> 
     </dependency> 

tanto sono un'eccezione differente. Fare riferimento - https://stackoverflow.com/questions/12176049/suggest-work-around-for-com-thoughtworks-xstream-converters-conversionexception

Ho anche provato con javassist versione 15 ma ottenere lo stesso problema

Si prega di aiutare ..

risposta

7

scoperto la soluzione io stesso:

Utilizzare le dipendenze di seguito (per Potenza Mock e Regola della potenza) solo

<!-- Required for PowerMock --> 
    <dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-api-mockito</artifactId> 
     <version>1.4.12</version> 
     <scope>test</scope> 
    </dependency> 
    <!-- Required for PowerMockRule --> 
    <dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-module-junit4-rule-agent</artifactId> 
     <version>1.4.12</version> 
     <scope>test</scope> 
    </dependency> 

Ora io non sto ottenendo una delle eccezioni di cui sopra

+0

Ho avuto lo stesso problema, l'aggiunta delle dipendenze sopra ha risolto il problema. Ma sto affrontando un altro problema, cioè il codice non sta colpendo il punto di rottura del debug. – aamir

+0

grazie amico che mi ha davvero aiutato molto :) –

+0

Non dimenticare di upvote :) – Bhuvan

2

Senza ulteriori esempi di codice ho capito che il codice sta usando Primavera nel test. Quindi credo che la ragione di questo errore sia quella relativa all'utilizzo di Spring, che sembra aver generato proxy JDK (lo $Proxy88).

E il modo in cui Powermock funziona è eseguendo il test JUnit in un nuovo classloader per modificare il bytecode di queste classi, sfortunatamente è possibile modificare il bytecode solo da un file reale, o almeno da un posizione in cui è possibile leggere il codice binario della classe, poiché java non può accedere al codice byte già caricato nella JVM. (Potrebbe essere possibile con un agente in modo limitato).

Poiché i proxy JDK non esistono sul disco, non possono essere letti o copiati nello specifico programma di caricamento della classe Powermock.

Il test che si sta scrivendo non è un test unitario poiché viene eseguito con un contesto Spring. Potresti voler scrivere un vero Test unitario prima. Quindi alcuni Test di integrazione, in cui non avrete bisogno di mazze.

Inoltre, si dovrebbe evitare l'uso della statica, in quanto è un incubo di testabilità. Dovresti riscrivere il tuo codice di produzione in un modo in cui le chiamate statiche non devono essere prese in giro.

Cheers,

+0

grazie per la spiegazione. – ejaenv

0
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "classpath:/test-servlet.xml") 
public class ControlCenterManagerImplTest { 

@Rule 
public PowerMockRule rule = new PowerMockRule(); 

//Powermock agent initialization not required and using maven dependency specified above by BHUVAN we can execute Power mock using spring.} 
4

Sostituire modulo powermock-junit4-regola con powermock-module-junit4-ru le-agent.

<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-module-junit4-rule-agent</artifactId> 
    <scope>test</scope> 
</dependency> 

La principale differenza tra il programma di avvio automatico basato agente e il programma di avvio automatico basato classloading è che non si esegue in problemi classloading.

+0

Grazie @ tak3shi ha funzionato per me! Inoltre avevo bisogno di usare la flag -javaagent. – ejaenv