2016-07-18 109 views

risposta

9

Allo stato attuale, la verità gli autori consiglia di utilizzare il modello try/fallire/catch, in quanto questo è chiaro ed esplicito.

try { 
    doSomethingThatThrows(); 
    fail("method should throw"); 
} catch (SpecificException e) { 
    // ensure that e was thrown from the right code-path 
    // especially important if it's something as frequent 
    // as an IllegalArgumentException, etc. 
    assertThat(e).hasMessage("blah blah blah"); 
} 

Mentre @Rule ExpectedException e @Test(exception=...) esistono in JUnit, questi non sono raccomandati dal team di verità, nella misura in cui hanno alcuni modi sottili (e meno sottili) è possibile scrivere i test che passano ma che dovrebbe fallire.

Mentre questo vale anche per try/fail/catch, internamente Google lo mitiga con l'uso di error-prone, che fornisce un controllo statico in fase di compilazione per garantire che questo modello non ometta il fail(), ecc. Si consiglia vivamente di utilizzare questi controlli con analisi di errore o altri controlli statici. Purtroppo, i metodi basati su regole e annotazioni non sono facilmente interpretabili con l'analisi statica come questo blocco try/catch.


Detto questo, gli autori verità stanno lavorando su una caratteristica accogliente Java8, che dovrebbe essere simile a

assertThat(() -> doThrowingMethod()) 
    .named("doThrowingMethod()") 
    .throwsException(SomeException.class) 
    .withMessageContaining("Foo bar") 
    .withCause(OtherThrowable.class); 

Questo potrebbe essere utilizzato pre-java8, anche se sarebbe un po 'grossolano

ThrowingRunnable throwing = new ThrowingRunnable() { 
    @Override void run() throws Throwable { 
    doThrowingMethod(); 
    } 
}; 
assertThat(throwing) 
    .named("doThrowingMethod()") 
    .throwsException(SomeException.class) 
    .withMessageContaining("Foo bar") 
    .withCause(OtherThrowable.class); 

Nota: API speculativa totalmente soggetta a modifiche. Questa risposta verrà aggiornata quando la funzione atterra.Coloro che vogliono seguirlo possibile guardare Issue #219

0

Vuoi dire avete bisogno di qualcosa di simile:

 try { 

      //do here something that should throw exception 
      //... 
      assertTrue("expected exception when .......", false); 

     } catch (Exception ex) {} 

??

+2

Beh questo è una possibilità, ma secondo me è abbastanza brutto, simile a quello che ho usato per fare prima di Junit 4. Stavo pensando a qualcosa di più fluente del tipo: '' 'assertThat (" previsto "). willThrow (" whatever.class ")' '' – Imanol

+0

Stiamo cercando qualcosa di più robusto per Java8, che sarà tanto meno. Qualcosa come 'assertThat (foo) .whenRunning (() -> runMethod()) .throws (Throwable.class) .withMessage (" blah ");' –

+0

Er: 'assertThat (() -> runMethod()). (Throwable.class) .withMessage ("blah"); ' –

2

Attualmente non esiste un modo integrato per verificare un Exception previsto con google-truth. Si può fare in uno dei seguenti:

credo google-truth non ha una s funzionalità simile perché supports Java 1.6.

import com.google.common.truth.FailureStrategy; 
import com.google.common.truth.Subject; 
import com.google.common.truth.SubjectFactory; 
import org.junit.Test; 

import java.util.concurrent.Callable; 

import static com.google.common.truth.Truth.assertAbout; 

public class MathTest { 
    @Test 
    public void addExact_throws_ArithmeticException_upon_overflow() { 
     assertAbout(callable("addExact")) 
      .that(() -> Math.addExact(Integer.MAX_VALUE, 1)) 
      .willThrow(ArithmeticException.class); 
    } 

    static <T> SubjectFactory<CallableSubject<T>, Callable<T>> callable(String displaySubject) { 
     return new SubjectFactory<CallableSubject<T>, Callable<T>>() { 
      @Override public CallableSubject<T> getSubject(FailureStrategy fs, Callable<T> that) { 
       return new CallableSubject<>(fs, that, displaySubject); 
      } 
     }; 
    } 

    static class CallableSubject<T> extends Subject<CallableSubject<T>, Callable<T>> { 
     private final String displaySubject; 

     CallableSubject(FailureStrategy failureStrategy, Callable<T> callable, String displaySubject) { 
      super(failureStrategy, callable); 
      this.displaySubject = displaySubject; 
     } 

     @Override protected String getDisplaySubject() { 
      return displaySubject; 
     } 

     void willThrow(Class<?> clazz) { 
      try { 
       getSubject().call(); 
       fail("throws a", clazz.getName()); 
      } catch (Exception e) { 
       if (!clazz.isInstance(e)) { 
        failWithBadResults("throws a", clazz.getName(), "throws a", e.getClass().getName()); 
       } 
      } 
     } 
    } 
} 
+0

Stiamo cercando qualcosa di più robusto per Java8, che sarà tanto meno. Qualcosa sulla falsariga di 'assertThat (() -> runMethod()). Getta (Throwable.class) .withMessage (" blah ");' –

2

come aggiornamento qui, abbiamo allontanato dal modello cristiana descritta, e Issue #219 è stato chiuso a favore di JUnit di expectThrows() (in arrivo 4.13, metodi simili esistono già in TestNG's Assert).

In tandem con expectThrows() è possibile utilizzare la verità per rendere assertions about the thrown exception. Quindi l'esempio di Christian sarebbe ora:

SpecificException expected = expectThrows(
    SpecificException.class,() -> doSomethingThatThrows()); 
assertThat(expected).hasMessageThat().contains("blah blah blah");