2012-08-16 18 views
19

Sto provando a stubare un metodo usando Mockito 1.8.5, ma così facendo richiama l'implementazione del metodo reale (con "" come valori di parm) che genera un'eccezione .Mockito che chiama l'implementazione del metodo reale durante il tentativo di stub metodo protetto

package background.internal; //located in trunk/tests/java/background/internal 

public class MoveStepTest { 

    @Test 
    public void testMoveUpdate() { 
     final String returnValue = "value"; 
     final FileAttachmentContainer file = mock(FileAttachmentContainer.class); 
     doReturn(returnValue).when(file).moveAttachment(anyString(), anyString(), anyString()); 
     //this also fails 
     //when(file.moveAttachment(anyString(), anyString(), anyString())).thenReturn(returnValue); 

     final AttachmentMoveStep move = new AttachmentMoveStep(file); 
     final Action moveResult = move.advance(1, mock(Context.class)); 
     assertEquals(Action.done, moveResult); 
    } 
} 

Il metodo che sto cercando di simulare assomiglia a questo. Non ci sono metodi o classi finali.

package background.internal; //located in trunk/src/background/internal 


    public class FileAttachmentContainer { 
     String moveAttachment(final String arg1, final String arg2, final String arg3) 
       throws CustomException { 
      ... 
     } 

     String getPersistedValue(final Context context) { 
      ...  
     } 
    } 

E la classe sto passando gli sguardi finti come questo:

package background.internal; //located in trunk/src/background/internal 
public class AttachmentMoveStep { 

    private final FileAttachmentContainer file; 

    public AttachmentMoveStep(final FileAttachmentContainer file) { 
     this.file = file;   
    } 

    public Action advance(final double acceleration, final Context context) { 
     try { 
      final String attachmentValue = this.file.getPersistedValue(context); 
      final String entryId = this.file.moveAttachment(attachmentValue, "attachment", context.getUserName()); 

      //do some other stuff with entryId 
     } catch (CustomException e) { 
      e.log(context); 
     }  
     return Action.done; 
    } 
} 

cosa sta causando l'effettiva attuazione a essere invocate e come posso evitarlo?

+0

È possibile aggiungere il codice che sta effettivamente eseguendo il test? – jhericks

+1

È 'FileAttachmentContainer' o il metodo' moveAttachment() 'finale? Mockito non può prendere in giro i metodi finali. –

+0

MoveAttachment è realmente chiamato con i valori di anyString()? – markus

risposta

19

Il metodo che stai deridendo non è accessibile al codice Mockito.

Poiché il codice di test e il codice sotto test sono nello stesso pacchetto, il compilatore ti consente di configurare il tuo simulato in questo modo, ma in fase di esecuzione, la libreria Mockito deve provare ad accedere a moveAttachment, ma non funziona nel tuo Astuccio. Questo sembra essere un bug o known limitation in Mockito come dovrebbe supportare tale caso, (e infatti, lo supporta nella maggior parte dei casi).

La cosa più semplice da fare sarebbe quella di rendere moveAttachment un metodo pubblico. Se questa non è un'opzione, quindi prima domanda se vuoi anche deriderlo. Cosa succede se viene chiamato il metodo reale?

L'ultima opzione è utilizzare PowerMock per trattare il metodo moveAttachment come metodo privato e deriderlo in questo modo.

+0

Questo sembra essere il problema. Sembra anche che altre persone vi si siano imbattuti: http://code.google.com/p/mockito/issues/detail?id=127 Grazie –

+0

Questo non è corretto. In generale, Mockito può prendere in giro pacchetti di metodi privati ​​senza problemi. Questo bug sembra essere un problema con OSGi/jar sigillati o qualcosa di simile. –

+0

@ Arendv.Reinersdorff, se è vero, PowerMock farebbe ancora il trucco? Se è così, cambierò la mia risposta per cercare di riflettere meglio la parte "perché" di esso. – jhericks

0

Non sono d'accordo con la risposta accettata.

Penso che sia necessario fornire maggiori dettagli sul proprio ambiente. Non riesco a riprodurre il tuo problema. Scrivo il seguente codice in un progetto Maven:

package background.internal; //located in src/main/java 

public class FileAttachmentContainer { 
    String moveAttachment(String arg1, String arg2, String arg3) { 
     throw new IllegalStateException(); 
    } 

    String getPersistedValue(Context context) { 
     throw new IllegalStateException(); 
    } 
} 

e

package background.internal; 

public class AttachmentMoveStep { 

    private FileAttachmentContainer file; 

    public AttachmentMoveStep(FileAttachmentContainer file) { 
     this.file = file; 
    } 

    public Action advance(double acceleration, Context context) { 
     String attachmentValue = file.getPersistedValue(context); 
     file.moveAttachment(attachmentValue, "attachment", context.getUserName()); 
     return Action.done; 
    } 
} 

e il successivo passaggio di prova

package background.internal; //located in src/test/java 

import static org.junit.Assert.assertEquals; 
import static org.mockito.Matchers.anyString; 
import static org.mockito.Mockito.doReturn; 
import static org.mockito.Mockito.mock; 

import org.junit.Test; 

public class MoveStepTest { 

    @Test 
    public void testMoveUpdate() { 
     String returnValue = "value"; 
     FileAttachmentContainer file = mock(FileAttachmentContainer.class); 
     doReturn(returnValue).when(file).moveAttachment(anyString(), anyString(), anyString()); 
     //this also works 
     //when(file.moveAttachment(anyString(), anyString(), anyString())).thenReturn(returnValue); 

     AttachmentMoveStep move = new AttachmentMoveStep(file); 
     Action moveResult = move.advance(1, mock(Context.class)); 
     assertEquals(Action.done, moveResult); 
    } 
} 

Il mio progetto utilizzare le seguenti dipendenze:

  • jdk1.7.0_05
  • junit-4.10.jar
  • Mockito-all-1.9.0.jar
  • javassist-3.16.1-GA.jar
  • objenesis-1.2.jar
  • hamcrest-core-1.1.jar
+3

Questa non è una risposta. Sta solo affermando che non riesci a capire perché l'interrogante stia avendo il problema. La domanda era: "Che cosa sta causando la vera implementazione da invocare e come posso impedirlo?" Ho risposto alla parte "come posso prevenirlo", ma ho solo supposato sulla parte "Cosa sta causando". Questa risposta non ha né Questa risposta dice solo che dovrebbe funzionare e non sai perché non lo fa. – jhericks

+0

@jhericks, hai ragione, non so perché e per me questo è un problema. Penso che dobbiamo arrivare fino in fondo alla cosa e trovare la causa alla radice del problema. Non solo fornire una soluzione alternativa. – gontard

+0

@gontard Hai compilato in due vasi separati? Uno con il test e uno con l'implementazione? –

Problemi correlati