### Question:
ExponentialBackoffStrategy implements TimeoutStrategy { @Override public Timeout newTimeout() { return new Timeout() { private long backoffTimeMillis = initialBackoffTimeMillis; @Override public long getMillis() { return backoffTimeMillis; } @Override public void increment() { backoffTimeMillis = Math.min( backoffTimeMillis * 2, upperBoundBackoffTimeMillis ); } }; } ExponentialBackoffStrategy( long initialBackoffTime, long upperBoundBackoffTime, TimeUnit timeUnit );  ExponentialBackoffStrategy( Duration initialBackoffTime, Duration upperBoundBackoffTime ); @Override Timeout newTimeout();  }### Answer:
@Test public void shouldDoubleEachTime() { ExponentialBackoffStrategy strategy = new ExponentialBackoffStrategy( 1, 1 << NUMBER_OF_ACCESSES, MILLISECONDS ); TimeoutStrategy.Timeout timeout = strategy.newTimeout(); for ( int i = 0; i < NUMBER_OF_ACCESSES; i++ ) { timeout.increment(); } assertEquals( 1 << NUMBER_OF_ACCESSES, timeout.getMillis() ); }
@Test public void shouldProvidePreviousTimeout() { ExponentialBackoffStrategy strategy = new ExponentialBackoffStrategy( 1, 1 << NUMBER_OF_ACCESSES, MILLISECONDS ); TimeoutStrategy.Timeout timeout = strategy.newTimeout(); for ( int i = 0; i < NUMBER_OF_ACCESSES; i++ ) { timeout.increment(); } assertEquals( 1 << NUMBER_OF_ACCESSES, timeout.getMillis() ); }
@Test public void shouldRespectUpperBound() { long upperBound = (1 << NUMBER_OF_ACCESSES) - 5; ExponentialBackoffStrategy strategy = new ExponentialBackoffStrategy( 1, upperBound, MILLISECONDS ); TimeoutStrategy.Timeout timeout = strategy.newTimeout(); for ( int i = 0; i < NUMBER_OF_ACCESSES; i++ ) { timeout.increment(); } assertEquals( upperBound, timeout.getMillis() ); timeout.increment(); timeout.increment(); timeout.increment(); assertEquals( upperBound, timeout.getMillis() ); }