Home | History | Annotate | Download | only in mockitoutil
      1 package org.mockitoutil;
      2 
      3 import org.junit.runner.Result;
      4 import org.junit.runner.notification.Failure;
      5 
      6 import java.util.List;
      7 
      8 import static org.junit.Assert.assertEquals;
      9 import static org.mockito.internal.util.collections.Iterables.firstOf;
     10 import static org.mockitoutil.TestBase.filterLineNo;
     11 
     12 /**
     13  * Assertion utility for cleaner & easier to debug tests that inspect on JUnit's Result object
     14  */
     15 public class JUnitResultAssert {
     16     private Result result;
     17 
     18     private JUnitResultAssert(Result result) {
     19         this.result = result;
     20     }
     21 
     22     public void isSuccessful() {
     23         if (result.wasSuccessful()) {
     24             return;
     25         }
     26 
     27         throw new AssertionError(formatFailures(result.getFailures()));
     28     }
     29 
     30     /**
     31      * @param expectedFailureCount - expected number of failures
     32      * @param expectedException - the exception of each failure
     33      */
     34     public JUnitResultAssert fails(int expectedFailureCount, Class expectedException) {
     35         fails(expectedFailureCount);
     36         for (Failure f : result.getFailures()) {
     37             if (!expectedException.isInstance(f.getException())) {
     38                 throw new AssertionError("Incorrect failure type, expected: " + expectedException + ", actual: " + f.getException().getClass().getSimpleName() + "\n" +
     39                         formatFailures(result.getFailures()));
     40             }
     41         }
     42         return this;
     43     }
     44 
     45     /**
     46      * @param expectedFailureCount - exact number of expected failures
     47      */
     48     public JUnitResultAssert fails(int expectedFailureCount) {
     49         if (result.getFailures().size() != expectedFailureCount) {
     50             throw new AssertionError("Wrong number of failures, expected: " + expectedFailureCount + ", actual: " + result.getFailures().size() + "\n" +
     51                     formatFailures(result.getFailures()));
     52         }
     53         return this;
     54     }
     55 
     56     /**
     57      * @param expectedExceptions - failures must match the supplied sequence in order,
     58      *                           if supplied input is empty, this method is a no-op
     59      */
     60     public JUnitResultAssert failsExactly(Class ... expectedExceptions) {
     61         fails(expectedExceptions.length);
     62         int i = 0;
     63         for (Failure f : result.getFailures()) {
     64             if (!expectedExceptions[i].isInstance(f.getException())) {
     65                 throw new AssertionError("Actual failure #" + (i+1)
     66                         + " should be of type: " + expectedExceptions[i].getSimpleName()
     67                         + " but is of type: " + f.getException().getClass().getSimpleName()
     68                         + "\n" + formatFailures(result.getFailures()));
     69             }
     70             i++;
     71         }
     72         return this;
     73     }
     74 
     75     /**
     76      * Expects single failure with specific exception and exception message.
     77      * Automatically filters line numbers from exception messages.
     78      */
     79     public JUnitResultAssert fails(Class expectedException, String exceptionMessage) {
     80         fails(1, expectedException);
     81         Failure f = firstOf(result.getFailures());
     82         assertEquals(filterLineNo(exceptionMessage), filterLineNo(f.getException().getMessage()));
     83         return this;
     84     }
     85 
     86     /**
     87      * Expects failure of given test method with given exception
     88      */
     89     public JUnitResultAssert fails(String methodName, Class expectedException) {
     90         for (Failure f : result.getFailures()) {
     91             if (methodName.equals(f.getDescription().getMethodName()) && expectedException.isInstance(f.getException())) {
     92                 return this;
     93             }
     94         }
     95         throw new AssertionError("Method '" + methodName + "' did not fail with: " + expectedException.getSimpleName()
     96                 + "\n" + formatFailures(result.getFailures()));
     97     }
     98 
     99     /**
    100      * Expects given amount of failures, with given exception triggered by given test method
    101      */
    102     public JUnitResultAssert fails(int expectedFailureCount, String methodName, Class expectedException) {
    103         return fails(expectedFailureCount, expectedException)
    104                 .fails(methodName, expectedException);
    105     }
    106 
    107     public JUnitResultAssert succeeds(int successCount) {
    108         int i = result.getRunCount() - result.getFailureCount();
    109         if (i != successCount) {
    110             throw new AssertionError("Expected " + successCount + " passes but " + i + "/" + result.getRunCount() + " passed." +
    111                     "\n" + formatFailures(result.getFailures()));
    112         }
    113         return this;
    114     }
    115 
    116     private static String formatFailures(List<Failure> failures) {
    117         if (failures.isEmpty()) {
    118             return "<no failures>";
    119         }
    120         StringBuilder sb = new StringBuilder("There were " + failures.size() + " test failures:\n");
    121         int count = 0;
    122         for (Failure f : failures) {
    123             sb.append("  <-----> ").append(++count).append(". ").append(f.getTrace()).append("\n");
    124         }
    125 
    126         return sb.toString();
    127     }
    128 
    129     /**
    130      * Clean assertions for JUnit's result object
    131      */
    132     public static JUnitResultAssert assertThat(Result result) {
    133         return new JUnitResultAssert(result);
    134     }
    135 }
    136