MessageTracker { public Context received(final Object message) { if (!expectedMessageWatch.isRunning()) { return NO_OP_CONTEXT; } if (expectedMessageClass.isInstance(message)) { final long actualElapsedTime = expectedMessageWatch.elapsed(NANOSECONDS); if (actualElapsedTime > expectedArrivalInterval) { return new ErrorContext(message, new FailedExpectation(lastExpectedMessage, message, messagesSinceLastExpectedMessage, expectedArrivalInterval, actualElapsedTime)); } lastExpectedMessage = message; messagesSinceLastExpectedMessage.clear(); expectedMessageWatch.reset().start(); } currentMessageContext.reset(message); return currentMessageContext; } @VisibleForTesting  MessageTracker(final Class<?> expectedMessageClass, final long expectedArrivalIntervalInMillis,
            final Ticker ticker);  MessageTracker(final Class<?> expectedMessageClass, final long expectedArrivalIntervalInMillis); void begin(); Context received(final Object message); List<MessageProcessingTime> getMessagesSinceLastExpectedMessage();  }
@Test public void testNoTracking() { MessageTracker.Context context1 = messageTracker.received(new Foo()); context1.close(); ticker.advance(20, MILLISECONDS); MessageTracker.Context context2 = messageTracker.received(new Foo()); context2.close(); }
@Test public void testNoIllegalStateExceptionWhenDoneIsNotCalledWhileNotTracking() { messageTracker.received(new Foo()); messageTracker.received(new Foo()); }