• 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 package org.mockito.internal.verification;
6 
7 import org.mockito.exceptions.base.MockitoAssertionError;
8 import org.mockito.internal.util.Timer;
9 import org.mockito.internal.verification.api.VerificationData;
10 import org.mockito.verification.VerificationMode;
11 
12 /**
13  * Verifies that another verification mode (the delegate) is satisfied within a certain timeframe
14  * (before timeoutMillis has passed, measured from the call to verify()), and either returns immediately
15  * once it does, or waits until it is definitely satisfied once the full time has passed.
16  */
17 public class VerificationOverTimeImpl implements VerificationMode {
18 
19     private final long pollingPeriodMillis;
20     private final VerificationMode delegate;
21     private final boolean returnOnSuccess;
22     private final Timer timer;
23 
24     /**
25      * Create this verification mode, to be used to verify invocation ongoing data later.
26      *
27      * @param pollingPeriodMillis The frequency to poll delegate.verify(), to check whether the delegate has been satisfied
28      * @param durationMillis The max time to wait (in millis) for the delegate verification mode to be satisfied
29      * @param delegate The verification mode to delegate overall success or failure to
30      * @param returnOnSuccess Whether to immediately return successfully once the delegate is satisfied (as in
31      *                        {@link org.mockito.verification.VerificationWithTimeout}, or to only return once
32      *                        the delegate is satisfied and the full duration has passed (as in
33      *                        {@link org.mockito.verification.VerificationAfterDelay}).
34      */
VerificationOverTimeImpl( long pollingPeriodMillis, long durationMillis, VerificationMode delegate, boolean returnOnSuccess)35     public VerificationOverTimeImpl(
36             long pollingPeriodMillis,
37             long durationMillis,
38             VerificationMode delegate,
39             boolean returnOnSuccess) {
40         this(pollingPeriodMillis, delegate, returnOnSuccess, new Timer(durationMillis));
41     }
42 
43     /**
44      * Create this verification mode, to be used to verify invocation ongoing data later.
45      *
46      * @param pollingPeriodMillis The frequency to poll delegate.verify(), to check whether the delegate has been satisfied
47      * @param delegate The verification mode to delegate overall success or failure to
48      * @param returnOnSuccess Whether to immediately return successfully once the delegate is satisfied (as in
49      *                        {@link org.mockito.verification.VerificationWithTimeout}, or to only return once
50      *                        the delegate is satisfied and the full duration has passed (as in
51      *                        {@link org.mockito.verification.VerificationAfterDelay}).
52      * @param timer Checker of whether the duration of the verification is still acceptable
53      */
VerificationOverTimeImpl( long pollingPeriodMillis, VerificationMode delegate, boolean returnOnSuccess, Timer timer)54     public VerificationOverTimeImpl(
55             long pollingPeriodMillis,
56             VerificationMode delegate,
57             boolean returnOnSuccess,
58             Timer timer) {
59         this.pollingPeriodMillis = pollingPeriodMillis;
60         this.delegate = delegate;
61         this.returnOnSuccess = returnOnSuccess;
62         this.timer = timer;
63     }
64 
65     /**
66      * Verify the given ongoing verification data, and confirm that it satisfies the delegate verification mode
67      * before the full duration has passed.
68      *
69      * In practice, this polls the delegate verification mode until it is satisfied. If it is not satisfied once
70      * the full duration has passed, the last error returned by the delegate verification mode will be thrown
71      * here in turn. This may be thrown early if the delegate is unsatisfied and the verification mode is known
72      * to never recover from this situation (e.g. {@link AtMost}).
73      *
74      * If it is satisfied before the full duration has passed, behaviour is dependent on the returnOnSuccess parameter
75      * given in the constructor. If true, this verification mode is immediately satisfied once the delegate is. If
76      * false, this verification mode is not satisfied until the delegate is satisfied and the full time has passed.
77      *
78      * @throws MockitoAssertionError if the delegate verification mode does not succeed before the timeout
79      */
80     @Override
verify(VerificationData data)81     public void verify(VerificationData data) {
82         AssertionError error = null;
83 
84         timer.start();
85         while (timer.isCounting()) {
86             try {
87                 delegate.verify(data);
88 
89                 if (returnOnSuccess) {
90                     return;
91                 } else {
92                     error = null;
93                 }
94             } catch (AssertionError e) {
95                 error = handleVerifyException(e);
96             }
97         }
98 
99         if (error != null) {
100             throw error;
101         }
102     }
103 
handleVerifyException(AssertionError e)104     private AssertionError handleVerifyException(AssertionError e) {
105         if (canRecoverFromFailure(delegate)) {
106             sleep(pollingPeriodMillis);
107             return e;
108         } else {
109             throw e;
110         }
111     }
112 
canRecoverFromFailure(VerificationMode verificationMode)113     protected boolean canRecoverFromFailure(VerificationMode verificationMode) {
114         return !(verificationMode instanceof AtMost
115                 || verificationMode instanceof NoMoreInteractions);
116     }
117 
copyWithVerificationMode(VerificationMode verificationMode)118     public VerificationOverTimeImpl copyWithVerificationMode(VerificationMode verificationMode) {
119         return new VerificationOverTimeImpl(
120                 pollingPeriodMillis, timer.duration(), verificationMode, returnOnSuccess);
121     }
122 
sleep(long sleep)123     private void sleep(long sleep) {
124         try {
125             Thread.sleep(sleep);
126         } catch (InterruptedException ie) {
127             throw new RuntimeException("Thread sleep has been interrupted", ie);
128         }
129     }
130 
isReturnOnSuccess()131     public boolean isReturnOnSuccess() {
132         return returnOnSuccess;
133     }
134 
getPollingPeriodMillis()135     public long getPollingPeriodMillis() {
136         return pollingPeriodMillis;
137     }
138 
getTimer()139     public Timer getTimer() {
140         return timer;
141     }
142 
getDelegate()143     public VerificationMode getDelegate() {
144         return delegate;
145     }
146 }
147