Repository: mockito/mockito
Issue: FR: add Mockito.timeout(java.time.Duration) and after(java.time.Duration)

Representing durations as `long`'s is very error prone. We've seen (and fixed) hundreds of unit mismatch bugs inside of Google.

We (Guava) have recently updated most of our public APIs to add `java.time.Duration`-based overloads. [Caffeine](https://github.com/ben-manes/caffeine/issues/221) and [Selenium](https://github.com/SeleniumHQ/selenium/issues/7187) have done so as well.

Basically, I'd like to see the following APIs added:
`Mockito.after(java.time.Duration)`
`Mockito.timeout(java.time.Duration)`

And ideally the `long`-accepting APIs would be deprecated.

Issue comments:
That would makes sense to me. Feel free to open a PR to add these methods.

@mockito/developers We have a lot of evidence of `long`s being misused in common API's. Do you have any concerns if we deprecate the `after(long)` in favor of `after(java.time.Duration)` (and the same for `timeout`)?
Ideally we'd plumb the `Duration` all the way through the various layers of Mockito:

- `org.mockito.verification.After`
- `org.mockito.verification.Timeout`
- `org.mockito.internal.verification.VerificationOverTimeImpl`
- `org.mockito.internal.util.Timer`

I assume `After` and `Timeout` need to maintain backwards compatibility, but the latter 2 are in an `internal` package - does that mean I don't need to maintain backwards compatibility? Am I free to make breaking changes to those APIs?

Yes, any API in `org.mockito.internal` is not included in our semver policy and we are free to change.
I second that, now that mockito 3 is java 8 based !

Pull request review comments:
This example is for the `timeout(Duration)` method. I think we should revert the sample in this  method, but add an additional sentence above that this is discouraged and `Duration.ofMillis` should be used instead.
Same as above.
Would it make sense to change this comparison to the relevant `Duration` method as well? Not sure how much it will provide us, but maybe it would prevent regressions later?
Nit: we indent with 4 spaces. I am surprised that spotless didn't format that, I will reconfigure the autoformatter to take care of that.
Done.
Done.
Done.
Done - the deprecation should serve as the method of discouraging use.
Done.

Patch that resolved the issue:
diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java
index af1ceb22e9..aea283881e 100644
--- a/src/main/java/org/mockito/Mockito.java
+++ b/src/main/java/org/mockito/Mockito.java
@@ -4,6 +4,8 @@
  */
 package org.mockito;
 
+import java.time.Duration;
+
 import org.mockito.exceptions.misusing.PotentialStubbingProblem;
 import org.mockito.exceptions.misusing.UnnecessaryStubbingException;
 import org.mockito.internal.InternalMockHandler;
@@ -886,15 +888,15 @@
  * <pre class="code"><code class="java">
  *   //passes when someMethod() is called no later than within 100 ms
  *   //exits immediately when verification is satisfied (e.g. may not wait full 100 ms)
- *   verify(mock, timeout(100)).someMethod();
+ *   verify(mock, timeout(Duration.ofMillis(100))).someMethod();
  *   //above is an alias to:
- *   verify(mock, timeout(100).times(1)).someMethod();
+ *   verify(mock, timeout(Duration.ofMillis(100)).times(1)).someMethod();
  *
  *   //passes as soon as someMethod() has been called 2 times under 100 ms
- *   verify(mock, timeout(100).times(2)).someMethod();
+ *   verify(mock, timeout(Duration.ofMillis(100)).times(2)).someMethod();
  *
  *   //equivalent: this also passes as soon as someMethod() has been called 2 times under 100 ms
- *   verify(mock, timeout(100).atLeast(2)).someMethod();
+ *   verify(mock, timeout(Duration.ofMillis(100)).atLeast(2)).someMethod();
  * </code></pre>
  *
  *
@@ -2846,10 +2848,45 @@ public static VerificationMode only() {
      * @param millis - duration in milliseconds
      *
      * @return object that allows fluent specification of the verification (times(x), atLeast(y), etc.)
+     * @deprecated Use {@link #timeout(Duration)} instead.
      */
     @CheckReturnValue
+    @Deprecated
     public static VerificationWithTimeout timeout(long millis) {
-        return new Timeout(millis, VerificationModeFactory.times(1));
+      return timeout(Duration.ofMillis(millis));
+    }
+
+    /**
+     * Verification will be triggered over and over until the given amount of time, allowing testing of async code.
+     * Useful when interactions with the mock object did not happened yet.
+     * Extensive use of {@code timeout()} method can be a code smell - there are better ways of testing concurrent code.
+     * <p>
+     * See also {@link #after(Duration)} method for testing async code.
+     * Differences between {@code timeout()} and {@code after} are explained in Javadoc for {@link #after(Duration)}.
+     *
+     * <pre class="code"><code class="java">
+     *   //passes when someMethod() is called no later than within 100 ms
+     *   //exits immediately when verification is satisfied (e.g. may not wait full 100 ms)
+     *   verify(mock, timeout(Duration.ofMillis(100))).someMethod();
+     *   //above is an alias to:
+     *   verify(mock, timeout(Duration.ofMillis(100)).times(1)).someMethod();
+     *
+     *   //passes as soon as someMethod() has been called 2 times under 100 ms
+     *   verify(mock, timeout(Duration.ofMillis(100)).times(2)).someMethod();
+     *
+     *   //equivalent: this also passes as soon as someMethod() has been called 2 times under 100 ms
+     *   verify(mock, timeout(Duration.ofMillis(100)).atLeast(2)).someMethod();
+     * </code></pre>
+     *
+     * See examples in javadoc for {@link Mockito} class
+     *
+     * @param timeout how long to wait before timing out
+     *
+     * @return object that allows fluent specification of the verification (times(x), atLeast(y), etc.)
+     */
+    @CheckReturnValue
+    public static VerificationWithTimeout timeout(Duration timeout) {
+        return new Timeout(timeout, VerificationModeFactory.times(1));
     }
 
     /**
@@ -2889,7 +2926,7 @@ public static VerificationWithTimeout timeout(long millis) {
      *   //1.
      *   mock.foo();
      *   verify(mock, after(1000)).foo();
-     *   //waits 1000 millis and succeeds
+     *   //waits 1 second and succeeds
      *
      *   //2.
      *   mock.foo();
@@ -2902,10 +2939,68 @@ public static VerificationWithTimeout timeout(long millis) {
      * @param millis - duration in milliseconds
      *
      * @return object that allows fluent specification of the verification
+     * @deprecated Use {@link #after(Duration)} instead.
      */
     @CheckReturnValue
+    @Deprecated
     public static VerificationAfterDelay after(long millis) {
-        return new After(millis, VerificationModeFactory.times(1));
+      return after(Duration.ofMillis(millis));
+    }
+
+    /**
+     * Verification will be triggered after given amount of time, allowing testing of async code.
+     * Useful when interactions with the mock object did not happened yet.
+     * Extensive use of {@code after()} method can be a code smell - there are better ways of testing concurrent code.
+     * <p>
+     * Not yet implemented to work with InOrder verification.
+     * <p>
+     * See also {@link #timeout(Duration)} method for testing async code.
+     * Differences between {@code timeout()} and {@code after()} are explained below.
+     *
+     * <pre class="code"><code class="java">
+     *   //passes after 100ms, if someMethod() has only been called once at that time.
+     *   verify(mock, after(Duration.ofMillis(100))).someMethod();
+     *   //above is an alias to:
+     *   verify(mock, after(Duration.ofMillis(100)).times(1)).someMethod();
+     *
+     *   //passes if someMethod() is called <b>*exactly*</b> 2 times, as tested after 100 millis
+     *   verify(mock, after(Duration.ofMillis(100)).times(2)).someMethod();
+     *
+     *   //passes if someMethod() has not been called, as tested after 100 millis
+     *   verify(mock, after(Duration.ofMillis(100)).never()).someMethod();
+     *
+     *   //verifies someMethod() after a given time span using given verification mode
+     *   //useful only if you have your own custom verification modes.
+     *   verify(mock, new After(Duration.ofMillis(100), yourOwnVerificationMode)).someMethod();
+     * </code></pre>
+     *
+     * <strong>timeout() vs. after()</strong>
+     * <ul>
+     *     <li>timeout() exits immediately with success when verification passes</li>
+     *     <li>after() awaits full duration to check if verification passes</li>
+     * </ul>
+     * Examples:
+     * <pre class="code"><code class="java">
+     *   //1.
+     *   mock.foo();
+     *   verify(mock, after(Duration.ofSeconds(1))).foo();
+     *   //waits 1 second and succeeds
+     *
+     *   //2.
+     *   mock.foo();
+     *   verify(mock, timeout(Duration.ofSeconds(1))).foo();
+     *   //succeeds immediately
+     * </code></pre>
+     *
+     * See examples in javadoc for {@link Mockito} class
+     *
+     * @param delay how to to wait before triggering verification
+     *
+     * @return object that allows fluent specification of the verification
+     */
+    @CheckReturnValue
+    public static VerificationAfterDelay after(Duration delay) {
+        return new After(delay, VerificationModeFactory.times(1));
     }
 
     /**
diff --git a/src/main/java/org/mockito/internal/exceptions/Reporter.java b/src/main/java/org/mockito/internal/exceptions/Reporter.java
index f661b81e5c..db8bbbeacc 100644
--- a/src/main/java/org/mockito/internal/exceptions/Reporter.java
+++ b/src/main/java/org/mockito/internal/exceptions/Reporter.java
@@ -10,6 +10,7 @@
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -863,12 +864,12 @@ public static MockitoException usingConstructorWithFancySerializable(Serializabl
         return new MockitoException("Mocks instantiated with constructor cannot be combined with " + mode + " serialization mode.");
     }
 
-    public static MockitoException cannotCreateTimerWithNegativeDurationTime(long durationMillis) {
+    public static MockitoException cannotCreateTimerWithNegativeDurationTime(Duration duration) {
         return new FriendlyReminderException(join(
                 "",
                 "Don't panic! I'm just a friendly reminder!",
                 "It is impossible for time to go backward, therefore...",
-                "You cannot put negative value of duration: (" + durationMillis + ")",
+                "You cannot put negative value of duration: (" + duration + ")",
                 "as argument of timer methods (after(), timeout())",
                 ""
         ));
diff --git a/src/main/java/org/mockito/internal/util/Timer.java b/src/main/java/org/mockito/internal/util/Timer.java
index 783f580c92..650e887660 100644
--- a/src/main/java/org/mockito/internal/util/Timer.java
+++ b/src/main/java/org/mockito/internal/util/Timer.java
@@ -6,38 +6,42 @@
 
 import static org.mockito.internal.exceptions.Reporter.cannotCreateTimerWithNegativeDurationTime;
 
+import java.time.Duration;
+import java.time.Instant;
+
 public class Timer {
 
-    private final long durationMillis;
-    private long startTime = -1;
+    private final Duration duration;
+    private Instant startTime = null;
 
-    public Timer(long durationMillis) {
-        validateInput(durationMillis);
-        this.durationMillis = durationMillis;
+    public Timer(Duration duration) {
+        validateInput(duration);
+        this.duration = duration;
     }
 
     /**
      * Informs whether the timer is still counting down.
      */
     public boolean isCounting() {
-        assert startTime != -1;
-        return System.currentTimeMillis() - startTime <= durationMillis;
+        assert startTime != null;
+        Duration elapsed = Duration.between(startTime, Instant.now());
+        return elapsed.compareTo(duration) <= 0;
     }
 
     /**
      * Starts the timer count down.
      */
     public void start() {
-        startTime = System.currentTimeMillis();
+        startTime = Instant.now();
     }
 
-    private void validateInput(long durationMillis) {
-        if (durationMillis < 0) {
-            throw cannotCreateTimerWithNegativeDurationTime(durationMillis);
+    private void validateInput(Duration duration) {
+        if (duration.isNegative()) {
+            throw cannotCreateTimerWithNegativeDurationTime(duration);
         }
     }
 
-    public long duration() {
-        return durationMillis;
+    public Duration duration() {
+        return duration;
     }
 }
diff --git a/src/main/java/org/mockito/internal/verification/VerificationOverTimeImpl.java b/src/main/java/org/mockito/internal/verification/VerificationOverTimeImpl.java
index 24ec61a90d..edcf77cf62 100644
--- a/src/main/java/org/mockito/internal/verification/VerificationOverTimeImpl.java
+++ b/src/main/java/org/mockito/internal/verification/VerificationOverTimeImpl.java
@@ -4,6 +4,8 @@
  */
 package org.mockito.internal.verification;
 
+import java.time.Duration;
+
 import org.mockito.exceptions.base.MockitoAssertionError;
 import org.mockito.internal.util.Timer;
 import org.mockito.internal.verification.api.VerificationData;
@@ -11,12 +13,12 @@
 
 /**
  * Verifies that another verification mode (the delegate) is satisfied within a certain timeframe
- * (before timeoutMillis has passed, measured from the call to verify()), and either returns immediately
+ * (before timeout has passed, measured from the call to verify()), and either returns immediately
  * once it does, or waits until it is definitely satisfied once the full time has passed.
  */
 public class VerificationOverTimeImpl implements VerificationMode {
 
-    private final long pollingPeriodMillis;
+    private final Duration pollingPeriod;
     private final VerificationMode delegate;
     private final boolean returnOnSuccess;
     private final Timer timer;
@@ -24,22 +26,22 @@ public class VerificationOverTimeImpl implements VerificationMode {
     /**
      * Create this verification mode, to be used to verify invocation ongoing data later.
      *
-     * @param pollingPeriodMillis The frequency to poll delegate.verify(), to check whether the delegate has been satisfied
-     * @param durationMillis The max time to wait (in millis) for the delegate verification mode to be satisfied
+     * @param pollingPeriod The frequency to poll delegate.verify(), to check whether the delegate has been satisfied
+     * @param duration The max time to wait for the delegate verification mode to be satisfied
      * @param delegate The verification mode to delegate overall success or failure to
      * @param returnOnSuccess Whether to immediately return successfully once the delegate is satisfied (as in
      *                        {@link org.mockito.verification.VerificationWithTimeout}, or to only return once
      *                        the delegate is satisfied and the full duration has passed (as in
      *                        {@link org.mockito.verification.VerificationAfterDelay}).
      */
-    public VerificationOverTimeImpl(long pollingPeriodMillis, long durationMillis, VerificationMode delegate, boolean returnOnSuccess) {
-        this(pollingPeriodMillis, delegate, returnOnSuccess, new Timer(durationMillis));
+    public VerificationOverTimeImpl(Duration pollingPeriod, Duration duration, VerificationMode delegate, boolean returnOnSuccess) {
+        this(pollingPeriod, delegate, returnOnSuccess, new Timer(duration));
     }
 
     /**
      * Create this verification mode, to be used to verify invocation ongoing data later.
      *
-     * @param pollingPeriodMillis The frequency to poll delegate.verify(), to check whether the delegate has been satisfied
+     * @param pollingPeriod The frequency to poll delegate.verify(), to check whether the delegate has been satisfied
      * @param delegate The verification mode to delegate overall success or failure to
      * @param returnOnSuccess Whether to immediately return successfully once the delegate is satisfied (as in
      *                        {@link org.mockito.verification.VerificationWithTimeout}, or to only return once
@@ -47,8 +49,8 @@ public VerificationOverTimeImpl(long pollingPeriodMillis, long durationMillis, V
      *                        {@link org.mockito.verification.VerificationAfterDelay}).
      * @param timer Checker of whether the duration of the verification is still acceptable
      */
-    public VerificationOverTimeImpl(long pollingPeriodMillis, VerificationMode delegate, boolean returnOnSuccess, Timer timer) {
-        this.pollingPeriodMillis = pollingPeriodMillis;
+    public VerificationOverTimeImpl(Duration pollingPeriod, VerificationMode delegate, boolean returnOnSuccess, Timer timer) {
+        this.pollingPeriod = pollingPeriod;
         this.delegate = delegate;
         this.returnOnSuccess = returnOnSuccess;
         this.timer = timer;
@@ -97,7 +99,7 @@ public void verify(VerificationData data) {
 
     private AssertionError handleVerifyException(AssertionError e) {
         if (canRecoverFromFailure(delegate)) {
-            sleep(pollingPeriodMillis);
+            sleep(pollingPeriod);
             return e;
         } else {
             throw e;
@@ -109,12 +111,12 @@ protected boolean canRecoverFromFailure(VerificationMode verificationMode) {
     }
 
     public VerificationOverTimeImpl copyWithVerificationMode(VerificationMode verificationMode) {
-        return new VerificationOverTimeImpl(pollingPeriodMillis, timer.duration(), verificationMode, returnOnSuccess);
+        return new VerificationOverTimeImpl(pollingPeriod, timer.duration(), verificationMode, returnOnSuccess);
     }
 
-    private void sleep(long sleep) {
+    private void sleep(Duration sleep) {
         try {
-            Thread.sleep(sleep);
+            Thread.sleep(sleep.toMillis());
         } catch (InterruptedException ie) {
             throw new RuntimeException("Thread sleep has been interrupted", ie);
         }
@@ -124,8 +126,8 @@ public boolean isReturnOnSuccess() {
         return returnOnSuccess;
     }
 
-    public long getPollingPeriodMillis() {
-        return pollingPeriodMillis;
+    public Duration getPollingPeriod() {
+        return pollingPeriod;
     }
 
     public Timer getTimer() {
diff --git a/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java b/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java
index 87d9076e00..0f3845b6cd 100644
--- a/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java
+++ b/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java
@@ -35,7 +35,7 @@ private VerificationMode wrapInOrder(VerificationWrapper<?> verificationWrapper,
         if (verificationMode instanceof VerificationOverTimeImpl) {
             final VerificationOverTimeImpl verificationOverTime = (VerificationOverTimeImpl)verificationMode;
             if (verificationOverTime.isReturnOnSuccess()) {
-                return new VerificationOverTimeImpl(verificationOverTime.getPollingPeriodMillis(),
+                return new VerificationOverTimeImpl(verificationOverTime.getPollingPeriod(),
                         verificationOverTime.getTimer().duration(),
                         wrapInOrder(verificationWrapper, verificationOverTime.getDelegate(), inOrder),
                         verificationOverTime.isReturnOnSuccess());
diff --git a/src/main/java/org/mockito/verification/After.java b/src/main/java/org/mockito/verification/After.java
index 54d7453022..a65a244ef7 100644
--- a/src/main/java/org/mockito/verification/After.java
+++ b/src/main/java/org/mockito/verification/After.java
@@ -4,6 +4,8 @@
  */
 package org.mockito.verification;
 
+import java.time.Duration;
+
 import org.mockito.internal.verification.VerificationOverTimeImpl;
 import org.mockito.internal.verification.VerificationWrapper;
 
@@ -20,13 +22,25 @@ public class After extends VerificationWrapper<VerificationOverTimeImpl> impleme
      * <p>
      * Typically, you won't use this class explicitly. Instead use timeout() method on Mockito class.
      * See javadoc for {@link VerificationWithTimeout}
+     * @deprecated Use {@link After#After(Duration, VerificationMode)} instead.
      */
+    @Deprecated
     public After(long delayMillis, VerificationMode verificationMode) {
-        this(10, delayMillis, verificationMode);
+        this(Duration.ofMillis(delayMillis), verificationMode);
+    }
+
+    /**
+     * See the javadoc for {@link VerificationAfterDelay}
+     * <p>
+     * Typically, you won't use this class explicitly. Instead use timeout() method on Mockito class.
+     * See javadoc for {@link VerificationWithTimeout}
+     */
+    public After(Duration delay, VerificationMode verificationMode) {
+        this(Duration.ofMillis(10), delay, verificationMode);
     }
 
-    After(long pollingPeriod, long delayMillis, VerificationMode verificationMode) {
-        this(new VerificationOverTimeImpl(pollingPeriod, delayMillis, verificationMode, false));
+    After(Duration pollingPeriod, Duration delay, VerificationMode verificationMode) {
+        this(new VerificationOverTimeImpl(pollingPeriod, delay, verificationMode, false));
     }
 
     After(VerificationOverTimeImpl verificationOverTime) {
diff --git a/src/main/java/org/mockito/verification/Timeout.java b/src/main/java/org/mockito/verification/Timeout.java
index 99dcc45f53..b7679abf26 100644
--- a/src/main/java/org/mockito/verification/Timeout.java
+++ b/src/main/java/org/mockito/verification/Timeout.java
@@ -6,6 +6,8 @@
 
 import static org.mockito.internal.exceptions.Reporter.atMostAndNeverShouldNotBeUsedWithTimeout;
 
+import java.time.Duration;
+
 import org.mockito.internal.util.Timer;
 import org.mockito.internal.verification.VerificationOverTimeImpl;
 import org.mockito.internal.verification.VerificationWrapper;
@@ -23,23 +25,35 @@ public class Timeout extends VerificationWrapper<VerificationOverTimeImpl> imple
      * <p>
      * Typically, you won't use this class explicitly. Instead use timeout() method on Mockito class.
      * See javadoc for {@link VerificationWithTimeout}
+     * @deprecated Use {@link Timeout#Timeout(Duration, VerificationMode)} instead.
      */
+    @Deprecated
     public Timeout(long millis, VerificationMode delegate) {
-        this(10, millis, delegate);
+        this(Duration.ofMillis(millis), delegate);
+    }
+
+    /**
+     * See the javadoc for {@link VerificationWithTimeout}
+     * <p>
+     * Typically, you won't use this class explicitly. Instead use timeout() method on Mockito class.
+     * See javadoc for {@link VerificationWithTimeout}
+     */
+    public Timeout(Duration timeout, VerificationMode delegate) {
+        this(Duration.ofMillis(10), timeout, delegate);
     }
 
     /**
      * See the javadoc for {@link VerificationWithTimeout}
      */
-    Timeout(long pollingPeriodMillis, long millis, VerificationMode delegate) {
-        this(new VerificationOverTimeImpl(pollingPeriodMillis, millis, delegate, true));
+    Timeout(Duration pollingPeriod, Duration timeout, VerificationMode delegate) {
+        this(new VerificationOverTimeImpl(pollingPeriod, timeout, delegate, true));
     }
 
     /**
      * See the javadoc for {@link VerificationWithTimeout}
      */
-    Timeout(long pollingPeriodMillis, VerificationMode delegate, Timer timer) {
-        this(new VerificationOverTimeImpl(pollingPeriodMillis, delegate, true, timer));
+    Timeout(Duration pollingPeriod, VerificationMode delegate, Timer timer) {
+        this(new VerificationOverTimeImpl(pollingPeriod, delegate, true, timer));
     }
 
     Timeout(VerificationOverTimeImpl verificationOverTime) {


Test patch:
diff --git a/src/test/java/org/mockito/internal/util/TimerTest.java b/src/test/java/org/mockito/internal/util/TimerTest.java
index 8a4a173e02..2f2885b0da 100644
--- a/src/test/java/org/mockito/internal/util/TimerTest.java
+++ b/src/test/java/org/mockito/internal/util/TimerTest.java
@@ -4,6 +4,8 @@
  */
 package org.mockito.internal.util;
 
+import java.time.Duration;
+
 import org.assertj.core.api.Assertions;
 import org.junit.Rule;
 import org.junit.Test;
@@ -18,7 +20,7 @@ public class TimerTest extends TestBase {
     @Test
     public void should_return_true_if_task_is_in_acceptable_time_bounds() {
         //given
-        long duration = 10000L;
+        Duration duration = Duration.ofSeconds(10);
         Timer timer = new Timer(duration);
 
         //when
@@ -31,7 +33,7 @@ public void should_return_true_if_task_is_in_acceptable_time_bounds() {
     @Test
     public void should_return_false_when_time_run_out() throws Exception {
         //given
-        Timer timer = new Timer(0);
+        Timer timer = new Timer(Duration.ZERO);
         timer.start();
 
         //when
@@ -45,7 +47,7 @@ public void should_return_false_when_time_run_out() throws Exception {
     public void should_throw_friendly_reminder_exception_when_duration_is_negative() {
         expectedException.expect(FriendlyReminderException.class);
         expectedException.expectMessage("Don't panic! I'm just a friendly reminder!");
-        new Timer(-1);
+        new Timer(Duration.ofMillis(-1));
     }
 
     private void oneMillisecondPasses() throws InterruptedException {
diff --git a/src/test/java/org/mockito/internal/verification/VerificationOverTimeImplTest.java b/src/test/java/org/mockito/internal/verification/VerificationOverTimeImplTest.java
index 82cceeaea7..5f206c5420 100644
--- a/src/test/java/org/mockito/internal/verification/VerificationOverTimeImplTest.java
+++ b/src/test/java/org/mockito/internal/verification/VerificationOverTimeImplTest.java
@@ -9,6 +9,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.MockitoAnnotations.initMocks;
 
+import java.time.Duration;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -29,7 +31,8 @@ public class VerificationOverTimeImplTest {
     @Before
     public void setUp() {
         initMocks(this);
-        impl = new VerificationOverTimeImpl(10, 1000, delegate, true);
+        impl = new VerificationOverTimeImpl(
+            Duration.ofMillis(10), Duration.ofSeconds(1), delegate, true);
     }
 
     @Test
diff --git a/src/test/java/org/mockito/verification/TimeoutTest.java b/src/test/java/org/mockito/verification/TimeoutTest.java
index ae6e5d2e84..3719ae4215 100644
--- a/src/test/java/org/mockito/verification/TimeoutTest.java
+++ b/src/test/java/org/mockito/verification/TimeoutTest.java
@@ -7,6 +7,8 @@
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.*;
 
+import java.time.Duration;
+
 import org.junit.Test;
 import org.mockito.InOrder;
 import org.mockito.Mock;
@@ -28,7 +30,7 @@ public class TimeoutTest extends TestBase {
 
     @Test
     public void should_pass_when_verification_passes() {
-        Timeout t = new Timeout(1, mode, timer);
+        Timeout t = new Timeout(Duration.ofMillis(1), mode, timer);
 
         when(timer.isCounting()).thenReturn(true);
         doNothing().when(mode).verify(data);
@@ -42,7 +44,7 @@ public void should_pass_when_verification_passes() {
 
     @Test
     public void should_fail_because_verification_fails() {
-        Timeout t = new Timeout(1, mode, timer);
+        Timeout t = new Timeout(Duration.ofMillis(1), mode, timer);
 
         when(timer.isCounting()).thenReturn(true, true, true, false);
         doThrow(error).
@@ -60,7 +62,7 @@ public void should_fail_because_verification_fails() {
 
     @Test
     public void should_pass_even_if_first_verification_fails() {
-        Timeout t = new Timeout(1, mode, timer);
+        Timeout t = new Timeout(Duration.ofMillis(1), mode, timer);
 
         when(timer.isCounting()).thenReturn(true, true, true, false);
         doThrow(error).
@@ -74,7 +76,7 @@ public void should_pass_even_if_first_verification_fails() {
 
     @Test
     public void should_try_to_verify_correct_number_of_times() {
-        Timeout t = new Timeout(10, mode, timer);
+        Timeout t = new Timeout(Duration.ofMillis(10), mode, timer);
 
         doThrow(error).when(mode).verify(data);
         when(timer.isCounting()).thenReturn(true, true, true, true, true, false);
diff --git a/src/test/java/org/mockitousage/verification/VerificationWithTimeoutTest.java b/src/test/java/org/mockitousage/verification/VerificationWithTimeoutTest.java
index 0c50578f6c..230b632910 100644
--- a/src/test/java/org/mockitousage/verification/VerificationWithTimeoutTest.java
+++ b/src/test/java/org/mockitousage/verification/VerificationWithTimeoutTest.java
@@ -10,6 +10,7 @@
 import static org.mockito.junit.MockitoJUnit.rule;
 import static org.mockitoutil.Stopwatch.createNotStarted;
 
+import java.time.Duration;
 import java.util.concurrent.TimeUnit;
 
 import org.assertj.core.api.Assertions;
@@ -57,6 +58,17 @@ public void should_verify_with_timeout() {
         verify(mock).oneArg('c'); //sanity check
     }
 
+    @Test
+    public void should_verify_with_timeout_duration() {
+        // when
+        async.runAfter(50, callMock('c'));
+        async.runAfter(500, callMock('c'));
+
+        // then
+        verify(mock, timeout(Duration.ofMillis(200)).only()).oneArg('c');
+        verify(mock).oneArg('c'); //sanity check
+    }
+
     @Test
     public void should_verify_with_timeout_and_fail() {
         // when
@@ -72,6 +84,21 @@ public void call() {
         //TODO let's have a specific exception vs. generic assertion error + message
     }
 
+    @Test
+    public void should_verify_with_timeout_and_fail_duration() {
+        // when
+        async.runAfter(200, callMock('c'));
+
+        // then
+        Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
+            @Override
+            public void call() {
+                verify(mock, timeout(Duration.ofMillis(50)).only()).oneArg('c');
+            }
+        }).isInstanceOf(AssertionError.class).hasMessageContaining("Wanted but not invoked");
+        //TODO let's have a specific exception vs. generic assertion error + message
+    }
+
     @Test
     @Ignore //TODO nice to have
     public void should_verify_with_timeout_and_fail_early() {