2015-04-13 24 views
5

Sono di fronte a un problema con i test di Mockito junit. Sono nuovo ad esso e sono un po 'confuso con il problema che sto affrontando. Qualsiasi aiuto su questo sarebbe apprezzato.Mockito NotaMockException

class Activity{ 

    public void firstMethod(){ 

     String str = secondMethod(); 
    } 

    public String secondMethod(){ 
     String str = null; 

     /* some Code */ 

     return str; 
    } 
} 

Ottenere eccezione:

*org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to when() is not a mock!* 

nel seguente codice

class ActivityTest(){ 

    Activity act; 

    @Before 
    public void setup(){ 
    act = new Activity(); 
    } 

    @Test 
    public void testFirstMethod(){ 

     Mockito.doReturn(Mockito.anyString()).when(act).secondMethod(); 
     act.firstMethod(); 
     verify(act).secondMethod(); 
    } 
} 

Sono consapevole che l'attività non è una finta, ma io non sono sicuro di un modo per aggirare questo come secondMethod() è un metodo nella stessa classe. Devo scrivere la regola per secondMethod() poiché ho già eseguito il test delle unità. La definizione di secondMethod() include dipendenze esterne. Devo prendere in giro le dipendenze esterne presenti in secondMethod() e scrivere regole per loro piuttosto che governare per secondMethod()?

Ho trovato questo post: Mockito Spy'ing on the object being unit tested Tuttavia separare il secondoMetodo() in una classe diversa non ha senso. Il mio metodo è legato a questa classe. Creare una classe diversa per i test non mi sembra giusta. Anche deridere la classe reale usando spy() non è il modo più corretto come già spiegato nel post.

Non penso che dovrei creare una simulazione della classe Activity in quanto è la classe che sto testando. Apprezzerei molto l'aiuto e le intuizioni su questo.

+1

Non dovresti _mock_ away dei metodi della classe sotto test. E hai ragione - non dovresti prendere in giro la classe stessa. Invece, il mocking è progettato per sostituire tutti i collaboratori della classe sotto test. Quindi se la tua classe dipende da altre classi le cui istanze sono usate nei tuoi metodi, allora basta deridere quei collaboratori. – Seelenvirtuose

+1

L'eccezione è abbastanza chiara, l'atto non è un mock, quindi no quando() su di esso. Alcuni [doc] (https: // github.com/mockito/mockito/wiki/FAQ) dovresti leggere IMHO –

risposta

12

Come si è notato, act non è un mock, e quindi non è possibile registrare il comportamento su di esso. È possibile utilizzare Mockito.spy per, beh, spiare (o parzialmente deridere) l'oggetto act in modo da registrare solo il comportamento di secondMethod ed eseguire il codice effettivo per firstMethod.

Si noti, tuttavia, che matchers non può essere utilizzato in doReturn chiamate regardles di come si sta mock ing o spy ing l'oggetto. Un valore di ritorno deve essere un oggetto concreto.

class ActivityTest() { 

    Activity act; 

    @Before 
    public void setup(){ 
    act = Mockito.spy(new Activity()); // Here! 
    } 

    @Test 
    public void testFirstMethod(){ 

     Mockito.doReturn("someString").when(act).secondMethod(); 
     act.firstMethod(); 
     verify(act).secondMethod(); 
    } 
} 

una sintassi leggermente più elegante consente di utilizzare le annotazioni invece di chiamare in modo esplicito Mockito.spy, ma è una questione di gusto davvero:

@RunWith(MockitoJUnitRunner.class) 
class ActivityTest() { 

    @Spy 
    Activity act = new Activity(); 

    @Test 
    public void testFirstMethod(){ 

     Mockito.doReturn("someString").when(act).secondMethod(); 
     act.firstMethod(); 
     verify(act).secondMethod(); 
    } 
} 
+0

come controllare il valore di str all'interno di firstmethod? – Sridhar

0

Ecco alcuni suggerimenti:

  1. Mock l'attività.
  2. Modificare il comportamento di secondMethod con when/then/doReturn
  3. Utilizzare doCallRealMethod quando viene richiamato firstMethod.

Spero che sia d'aiuto.