2013-03-01 25 views
6

Sono nuovo anche per Mockito e PowerMockito. Ho scoperto che non posso testare metodi statici con Mockito puro, quindi ho bisogno di usare PowerMockito (giusto?).Per quale motivo dovrei prendere in giro?

ho molto semplice classe chiamata Convalida con questo metodo molto facile

public class Validate { 
     public final static void stateNotNull(
      final Object object, 
      final String message) { 
    if (message == null) { 
     throw new IllegalArgumentException("Exception message is a null object!"); 
    } 
    if (object == null) { 
     throw new IllegalStateException(message); 
    } 
} 

quindi ho bisogno di verificare che:

1) Quando chiamo quel metodo statico su questo argomento Messaggi null, IllegalArgumentException si chiama
2) Quando chiamo quel metodo statico su argomenti oggetto null, IllegalStateException si chiama

Da quello che ho ottenuto finora, ho scritto questo test:

import static org.mockito.Matchers.anyString; 
import static org.mockito.Matchers.isNull; 

import org.junit.Before; 
import org.junit.runner.RunWith; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 
import org.testng.annotations.Test; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Validate.class) 
public class ValidateTestCase { 

    @Test(expectedExceptions = { IllegalStateException.class }) 
    public void stateNotNullTest() throws Exception { 
     PowerMockito.mockStatic(Validate.class); 
     Validate mock = PowerMockito.mock(Validate.class); 
     PowerMockito.doThrow(new IllegalStateException()) 
      .when(mock) 
      .stateNotNull(isNull(), anyString()); 
     Validate.stateNotNull(null, null); 
    } 
} 

Quindi questo dice che mi prendo gioco di classe Convalida e sto verificando che quando finta viene chiamato su quel metodo con argomento null come un oggetto e qualsiasi stringa come messaggio, un IllegalStateException viene generata.

Ora, davvero non capisco. Perché non posso chiamare direttamente quel metodo, lasciando cadere l'intera magia voodoo che deride quella classe statica? A me sembra che, a meno che non chiami Validate.stateNotNull, il test passi comunque ... Per quale motivo dovrei prenderlo in giro?

risposta

8

In primo luogo, decidere qual è il tuo obiettivo e cosa vuoi testare. Il test non sta testando il metodo della classe Validate, sta creando una simulazione che si comporta come quel metodo, come Fortega points out. Identifica ciò che stai testando (l'oggetto in prova) e di cosa hai bisogno per eseguire il test (i collaboratori), quindi guarda i collaboratori e decidi se sono cose facili da creare o se ti servono deriderli.

Per qualcosa come questa classe che non ha dipendenze da qualsiasi cosa, consiglierei di fare senza deridere interamente. Qui non c'è nulla che ha bisogno di beffardo, il test può essere scritto in questo modo:

import static org.junit.Assert.*; 

public class ValidateTestCase { 

    @Test 
    public void testHappyPath() throws Exception { 
     Validate.stateNotNull("", ""); 
    } 

    @Test 
    public void testNullMessage() throws Exception { 
     try { 
      Validate.stateNotNull(null, null); 
      fail(); 
     } 
     catch (IllegalStateException e) { 
      String expected = "Exception message is a null object!" 
      assertEquals(expected, e.getMessage()); 
     } 
    } 

    @Test(expected=IllegalStateException.class) 
    public void testNullObject() throws Exception { 
     Validate.stateNotNull(null, "test"); 
    } 
} 

e che ti dice se il codice fa quello che si vuole.

Non prendere in giro a meno che non vi sia una dipendenza che si desidera evitare di introdurre al test a causa del fatto che si tratti di una risorsa esterna (come un file system o database) o di qualche sottosistema complesso. I framework mock possono essere molto utili ma aggiungono complessità, possono sovra-specificare il comportamento delle cose che stanno testando, rendere i test fragili e rendere i test difficili da leggere. Fai senza di loro se puoi.

11

Non dovresti prendere in giro le classi e i metodi che stai testando. Dovresti solo prendere in giro i metodi necessari per eseguire il test stesso.

Ad esempio, se sono necessari alcuni oggetti da un servizio Web per eseguire un test, è possibile prendere in giro le chiamate al servizio Web, quindi non è necessario chiamare effettivamente il servizio Web.

Problemi correlati