0

I have written a class called ErrorHandingFiniteStateMachine, which basically does something like:

https://developers.google.com/safe-browsing/developers_guide_v3#RequestFrequencyHashes

Basically it has a function called ErrorHandlingFiniteStateMachine.update(), which will be called when the caller class receives an error. It will then update the error state, which depends on:

  • how many errors it has received;
  • how much time it has elapsed since last error;
  • and of course, the last error state.

Now my questions are:

  1. How to mock up the time elapsed in mockito, because the time can be very long, such as hours, and I definitely don't want to wait for several hours to finish a unit test.
  2. Is there any standard tutorial or best practice to test a state machine with time-related features?

EDIT

As folks pointed out, I use System.currentTimeMillis to remember the current timestamp. But BTW, the unit test is not supposed to know so much detailed info about the implementation, right?

MY SOLUTION

I finally wrapped System.currentTimeMillis() in the ErrorHandlingFiniteStateMachine.getCurrentTimestamp(), and make it package-private (no modifier), so it's accessible in my TestErrorHandlingFiniteStateMachine. Then I used a mockito spy to mock the ErrorHandlingFiniteStateMachine.getCurrentTimestamp()

Peter Lee
  • 12,931
  • 11
  • 73
  • 100
  • 3
    We can't see any of the code you're trying to test - which means we have no idea how you're getting the current time. Basically, that's the dependency you need to fake out. So if you're currently using `System.currentTimeMillis` or something like that, you need to stop - instead, have an interface representing a "current time service". – Jon Skeet Nov 28 '14 at 08:31
  • So basically, you are saying that, there is no way to test if we use `System.currentTimeMillis` or `new Date().getTime()`? In order to test it, we have to use a time service that can be both used in the real code and the unit test code? That sounds weird. I guess that's why I am asking if there is a way to fake the timing thing to kinda `shorten` the time we need to unit test it. – Peter Lee Nov 28 '14 at 08:47
  • You're calling static methods or constructors - while they *can* be mocked with PowerMock and the like, it's a much better idea (IMO) to isolate the dependency in a `Clock` object - then you'd normally inject an implementation which could use `new Date()` between the scenes, but for testing you can pass in a clock you control. – Jon Skeet Nov 28 '14 at 08:55
  • @PeterLee As Jon pointed out, you can mock (or fake) the system clock in Java, regardless of how it's accessed from the code under test. Whether it calls `System.currentTimeMillis()`, `System.nanoTime()`, or the Time API available in Java 8, it can always be mocked by using a mocking tool that is capable enough. For Java, we have PowerMock (which can be used with Mockito), and JMockit (which I develop). Personally, I see the alternative of injecting a `Clock` dependency as overkill in most real-world cases; I prefer the simplicity of using the standard Java APIs. – Rogério Nov 30 '14 at 16:26

0 Answers0