-2

In my Java application I have to write an Unit Test and I have to check that this test works in both time of the year Daylight savings time / Normal time. To do that, I should set an hardcoded datetime that override the server datetime; execute my test; and restore the real datetime.

How can I do that? I found this solution https://www.baeldung.com/java-override-system-time but is not what I really need (it only define a Instant entity to use in specific instruction, but I need to fix the desired date time and then to perform a test by using some methods not directly connected to an Instant).

Java.time would be preferred.

Edit

The test assigned to me should only read a data cell from an Excel file (formatted in Excel as Datetime) and make a comparison with a fixed date.

This is a detailed description:

  1. There is an Excel file with a cell formatted as "Datetime"

  2. I read this cell by

     Workbook excelWorkbook = new Workbook(excelFileStream, excelOptions);
     Cells cells = worksheet.getCells();
    
  3. A cell of the sheet if formatted by dateTime

  4. A method in my implementation read the cell and creates a Datetime var

That's all. My task is, create an Unit Test in order to check if the given value is always correct independent from the Daylight saving / Normal time of the year. I should "force" the local date time of the server, implement the test by creating something like

assertThat(ExcelCellDateTime).isEqualTo("<given date time>");

And restore the datetime of the Java application to the correct Date Time of the server. So the question is:

How can I simulate a certain datetime inside a unit test of my Java application, independent from the real date time of the server, such that the application 'believes' that the current datetime is the one I forced and the test can be executed 'as' now would be equal to the datetime I forced?

Comment on possible duplicate

I don't think this is a duplicate of the suggested question. I don't want to force a date and to compare the new date with something else, but I want to force the date and execute a test without the new date as parameter.

halfer
  • 19,824
  • 17
  • 99
  • 186
Archimede
  • 699
  • 3
  • 15
  • 28
  • 1
    Can you provide some code where this *datetime* is to be accessed/used? – deHaar May 17 '22 at 14:25
  • 1
    Hint: `java.time.ZonedDateTime` might be helpful when it comes to daylight saving times in different time zones (which are represented by the class `ZoneId` in `java.time`). – deHaar May 17 '22 at 14:28
  • 2
    Does the value read from the Excel cell have an offset from UTC or a time zone? If not, do you know which time zone or offset it is supposed to have? Again: Please add some code to the question by [edit]ing it. That's the way to get answers on stackoverflow… For now, I could just guess, which would be appropriate on a guessing site, which stackoverlow just isn't. – deHaar May 17 '22 at 14:38
  • 3
    Does this answer your question? [How to test date created with LocalDateTime.now()](https://stackoverflow.com/questions/39527752/how-to-test-date-created-with-localdatetime-now). You may also look at [this](https://stackoverflow.com/questions/52956373/writing-and-testing-convenience-methods-using-java-8-date-time-classes) and [this](https://stackoverflow.com/questions/61470651/how-to-change-the-value-new-date-in-java). – Ole V.V. May 17 '22 at 14:43
  • 1
    Does the comparison you are performing depend on system time? If so, I have not understood how. If not, why are you worrying about it at all? – Ole V.V. May 17 '22 at 14:46
  • 1
    Thank you very much for all your reply, now I will write all necessary info in the main question. – Archimede May 17 '22 at 14:48
  • Isn’t it a bit like asking to test `assertThat(2 + 2).isEqualTo(4)` at different times of year? If there is a fundamental difference, what is it? – Ole V.V. May 18 '22 at 07:16
  • Not really. The purpose of the test is really complex and not directly connected to my question and I don't want to bore the user with detail not directly connected to the problem. Anyway, thanks for trying. – Archimede May 18 '22 at 08:15
  • Well, if you are not sharing the details needed to understand your problem, do you think we can help? I appreciate, of course, that you don’t want to over-burden us. – Ole V.V. May 18 '22 at 08:30
  • Obviously not, but in this case the detail you mentioned are not needed to understand the problem of my question. My problem is only, how to force the current datetime, such that the application "believes" that the current datetime is the datetime I give. Noting else. Thank again anyway. – Archimede May 18 '22 at 08:33
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244837/discussion-between-ole-v-v-and-archimede). – Ole V.V. May 18 '22 at 12:02
  • Does this answer your question? [How can I set the System Time in Java?](https://stackoverflow.com/questions/6203857/how-can-i-set-the-system-time-in-java) (I added more depth in [the chat](https://chat.stackoverflow.com/rooms/244837/discussion-between-ole-v-v-and-archimede), please see it.) – Ole V.V. May 18 '22 at 12:08
  • 1
    Forget how you think this should be done, and explain what your application and its test actually do. Here are some specific problems with your question that you need to fix to get a better answer. "A method in my implementation read the cell and creates a Datetime var". What do you mean by "Datetime var"? Is it a `DateTime` instance from Joda time? Or just an imprecise reference to a nonspecific temporal type? A `String`? "I should ... implement the test by creating something like assertThat(ExcelCellDateTime).isEqualTo("")`. Why would you assert that the datetime is an empty string? – erickson May 19 '22 at 00:08
  • I have repaired spelling errors, typos, fixed code formatting, revealed hidden code, and fixed case errors in this post. Please use the preview window to ensure your post appears correctly before posting, and please install and use a spell-checker. – halfer May 25 '22 at 20:15
  • @halfer Thanks for those fixes. Given that information, this is indeed a duplicate. The attempt at clarification ("I want to force the date and execute a test without the new date as parameter") simply restates the duplicate question, as the duplicate answer doesn't use the new date as a parameter. – erickson May 31 '22 at 17:54

1 Answers1

2

Your business logic should be given a Clock instance to provide the current time (and time zone, when necessary) instead of using static methods like LocalDateTime.now() which hide a dependency on the environment. It's like a pluggable factory for various notions of "now."

When your logic uses a Clock, it is simple for tests to use clocks with a fixed time to test for correct behavior during daylight saving transitions, leap days, and other date-time corner cases.

Well-designed code is easy to use for any purpose, including testing. This sort of difficulty in testing is a symptom of poor design that indicates the code will be hard to reuse in other ways.

erickson
  • 265,237
  • 58
  • 395
  • 493