2013-01-09 13 views
5

Sto provando a prendere in giro la classe Query di JDBI con mockito, tuttavia non riesce a simulare i metodi della sua classe base SqlStatement.problemi di derisione di una classe

Quando si esegue il codice sotto l'istruzione when sta effettivamente chiamando l'implementazione concreta nella classe base e non riesce con NullPointerException.

Ho provato questo con EasyMock e ottenuto gli stessi risultati, non riesce a prendere in giro questo metodo.

Ulteriori informazioni:

  • versione Mockito è 1.9.5 versione
  • JDBI è 2.4.1 (quella che attualmente fornito con dropwizard)

L'eccezione è:

java.lang.NullPointerException 
     at org.skife.jdbi.v2.SQLStatement.bind(SQLStatement.java:434) 
     at TestClass.testBind(TestClass.java:17) 
      at .... 

Qualche idea su come aggirare questo problema?

+0

Questa non è una risposta, ma nella mia esperienza la derisione di questo tipo di codice DAO è una perdita di tempo. Non esporrà gli errori che fai nell'uso dell'API JDBI. Scrivi test su un vero database. – artbristol

risposta

4

bind metodi SqlStatement sono definitive (per exemple SQLStatement#bind(String, int)), quindi non si può deridere utilizzando Mockito, si tratta di una limitazione della JVM (EDIT :) che Mockito non può ignorare al momento.


EDIT2: Si noti che i commenti qui sotto punto fuori, c'è qualche incomprensione di ciò che è scritto sopra, e questo richiede un chiarimento da parte mia:

  • La limitazione della JVM significa che non è possibile caricare una sottoclasse di un tipo contrassegnato con un accesso finale, non è possibile sovrascrivere un metodo contrassegnato con l'accesso finale, altrimenti si otterrà un VerifyError. §8.1.1.2 final classes of the Java Language Specification§8.4.3.3 final methods of the JLS§4.10 of the Java Virtual Machine Specification
  • che Mockito non può ignorare significa Mockito non è attualmente in grado di superare classi finali o metodi finali per derisione, perché al momento Mockito utilizza CGLIB per generare sottoclassi del tipo di simulazione. Ma altri framework (come PowerMock o JMockit) potrebbero essere in grado di farlo in quanto hanno altre strategie per superare questo.

Le opzioni sono per cambiare la progettazione in modo da non dover stub tali interazioni, o si deve usare PowerMock che utilizza complicare trucchi con classloader per riscrivere classe bytecode (non è il mio approccio preferito, anche se PowerMock è tecnicamente impressionante).

Spero che questo aiuti.

+1

È una limitazione di Mockito, non della JVM, come implica il tuo commento che PowerMock supporta. Senza contare che anche JMockit * lo supporta, anche se non "usa trucchi complicati con i classloader". –

+0

@Rogerio Vedi la modifica: "quel mockito non può bypassare al momento" – Brice

+1

l'ho visto. Non è ancora una limitazione della JVM, come anche la documentazione ufficiale di Mockito [dice] (http://code.google.com/p/mockito/wiki/FAQ). (Ma mi sto ripetendo ...) Se c'è un obiettivo da "bypassare", suggerirei di incorporare il codice da PowerMockito (cioè, usando un classloader personalizzato). L'unica altra scelta sarebbe quella di usare l'approccio di JMockit, con l'uso di 'java.lang.instrument'. –

0

Prova

Mockito.doReturn(mockQuery).when(mockQuery).bind("xxx",5); 
+0

stesso errore, chiama ancora il metodo della classe base – LiorH

+0

Puoi pubblicare l'eccezione e la versione di Mockito che stai utilizzando. Ho appena eseguito in entrambi i modi con successo Mockito 1.9.0 e jdbi 2.9.4 – bstick12

+0

informazioni aggiunte – LiorH

Problemi correlati