1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 6 package org.mockitoutil; 7 8 import org.junit.rules.TestRule; 9 import org.junit.runner.Description; 10 import org.junit.runners.model.Statement; 11 12 import static java.lang.String.format; 13 14 public class RetryRule implements TestRule { 15 private final TestRule innerRule; 16 17 public static RetryRule attempts(final int attempts) { 18 return new RetryRule(new NumberedAttempts(attempts)); 19 } 20 21 private RetryRule(TestRule innerRule) { 22 this.innerRule = innerRule; 23 } 24 25 public Statement apply(final Statement base, final Description description) { 26 return innerRule.apply(base, description); 27 } 28 29 private static class NumberedAttempts implements TestRule { 30 private final int attempts; 31 32 NumberedAttempts(int attempts) { 33 assert attempts > 1; 34 this.attempts = attempts; 35 } 36 37 @Override 38 public Statement apply(final Statement base, final Description description) { 39 return new Statement() { 40 @Override 41 public void evaluate() throws Throwable { 42 for (int remainingAttempts = attempts; remainingAttempts > 0 ; remainingAttempts--) { 43 try { 44 base.evaluate(); 45 } catch (Throwable throwable) { 46 if (remainingAttempts < 0) { 47 throw new AssertionError(format("Tried this test + %d times and failed", attempts)) 48 .initCause(throwable); 49 } 50 } 51 } 52 } 53 }; 54 } 55 } 56 } 57