• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • Ron McLeod
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Junilu Lacar
  • Rob Spoor
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Tim Moores
  • Jesse Silverman
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Piet Souris
  • Frits Walraven

Mock ZonedDateTime now() method for junit coverage

 
s ravi chandran
Ranch Hand
Posts: 595
6
jQuery Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,
I have created a service which works based on time parameters. As part of the process, it also uses current time (ZonedDateTime.now()) method. Now I am stuck on this issue as I am unable to come up with a way to make the now() method return a static time so that my junit case run any time of the day and return fixed response.

I have created a crude mock up of my current implementation for reference :






Scenarios to test:
1. application start time is before host time
2. application end time is after host end time
3. process time within valid start and end time range, in this case start the process.

now my requirement is to somehow mock the NOW method of ZonedDateTime, so that I can perform all the expected results for this function.  

Please let me know any pointers on how I can do this.

Thanks

 
Tim Cooke
Marshal
Posts: 5215
323
IntelliJ IDE Python Java Linux
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is a common testing problem when the code you want to tests creates instances of objects that rely on environmental resources, such as time, or writing to outputs, or reading from inputs.

Thankfully there are things you can do to put your tests back in control of the environment. In your case I would recommend extracting the creation of a ZonedDateTime to its own method, after which you can employ a neat testing technique to inject your own value. For example:



I've massively simplified your code for illustration purposes, but you'll see that by extracting the creation of the ZonedDateTime object into a protected method I have been able to override it in my test class and have it return a value of my choosing. This gives the test class the ability to set the state of an object that you previously had no control over. It's a very powerful testing technique that you'll likely use over and over again.
 
s ravi chandran
Ranch Hand
Posts: 595
6
jQuery Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks a lot. This issue had troubled for many days, I kept getting stuck at how to either mock the clock or zonedDateTime.

This solution is very helpful.
 
Stephan van Hulst
Saloon Keeper
Posts: 13477
304
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please use the Clock class for this. This is exactly what it was created for.
 
Stephan van Hulst
Saloon Keeper
Posts: 13477
304
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are several issues with your code:

  • Make your classes final if you haven't meticulously designed them to be extensible.
  • Don't perform parsing or formatting in constructors. The only 'extra' work a constructor should do is defensive copying.
  • Validate your constructor parameters and copy mutable objects.
  • Don't use String fields in lieu of the strong types you're trying to represent. For instance, use ZonedDateTime instead of String in your Process class.
  • Use accurate names. A Process does not model an actual process, it's a description of a process.
  • Avoid printing to System.out in your business logic. If it is part of your requirement, move the printing as high up the call stack as possible.


  •  
    Rob Spoor
    Sheriff
    Posts: 22563
    122
    Eclipse IDE Spring VI Editor Chrome Java Windows
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Stephan is right, this is what Clock is for. I was even delighted to see that the Java Beans Validation framework allows you to specify a ClockProvider (basically a Supplier<Clock>). I've been able to use that quite a lot in my unit tests.

    Java 17 added a super interface for Clock: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/InstantSource.html. That can be used in a more generic way than just Clock.
     
    s ravi chandran
    Ranch Hand
    Posts: 595
    6
    jQuery Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks a lot for your responses. This is not the actual code from my project but a crude mock up with the scenario I wanted to show.  Apologies, if I was not clear earlier.

    My actual application follows standard design principals and gets reviewed by our senior technical team members.  We are currently on JDK 8.

    I do however am using the Clock class, will check the usage you had mentioned:

    In current scenario, the Clock instance is part of a utility class which is shared across many classes of same service.
     
    You showed up just in time for the waffles! And this tiny ad:
    Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
    https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
    reply
      Bookmark Topic Watch Topic
    • New Topic