• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
attempts(final int attempts)17     public static RetryRule attempts(final int attempts) {
18         return new RetryRule(new NumberedAttempts(attempts));
19     }
20 
RetryRule(TestRule innerRule)21     private RetryRule(TestRule innerRule) {
22         this.innerRule = innerRule;
23     }
24 
apply(final Statement base, final Description description)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 
NumberedAttempts(int attempts)32         NumberedAttempts(int attempts) {
33             assert attempts > 1;
34             this.attempts = attempts;
35         }
36 
37         @Override
apply(final Statement base, final Description description)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