Krešimir Nesek
Krešimir Nesek

Reputation: 5502

Time dependent unit tests breaking when run in parallel, any workarounds?

I have time dependent unit tests in which I have to simulate "now". I use JodaTime and when I need to simulate the value of now for purposes of time dependent testing I use DateTimeUtils.setCurrentMillisFixed(...), as suggested in the accepted answer in question Time dependent unit tests.

However, this has now caused problems when unit tests are run in parallel. Proper solution would be to make all classes obtain current time from a Clock dependency which could be mocked out in tests (as suggested in most upvoted answer in Time dependent unit tests). However, I will not have enough development resources to make that refactoring effort at the moment.

My question is is there a way to work around this by somehow specifying which tests may be run in parallel and which may not? Is there a way to work around this by using DateTimeUtils.setCurrentMillisProvider() ?

Testing framework is JUnit4, tests are run from maven.

Upvotes: 3

Views: 665

Answers (3)

Atais
Atais

Reputation: 11275

Already mentioned by Joe implementation of DateTimeUtils backed with ThreadLocal would do the job.

Sadly, nobody has provided such implementation.
You can find one in https://github.com/restx/restx project: HERE

And later in your tests you can manipulate the time with:

ThreadLocalMillisProvider.setCurrentMillisFixed(now.getMillis)
ThreadLocalMillisProvider.setCurrentMillisSystem()

With classes which use JodaTime under the hood.

Enjoy!

Upvotes: 0

Joe
Joe

Reputation: 31087

Implement and set a CurrentMillisProvider that stores "now" in a ThreadLocal<Long>, as suggested in these Parallelism Tips:

P.S. Joda Time has DateTimeUtils which lets you change the current time used by the library. It's a global variable, but if you call DateTimeUtils.setCurrentMillisProvider with a ThreadLocal backed implementation, it'll be reasonably isolated when testing legacy code that uses Joda Time.

Upvotes: 2

Peter Lawrey
Peter Lawrey

Reputation: 533500

If the tests are started from one thread you can use a InheritableThreadLocal to store the current time.

Upvotes: 0

Related Questions