-2

What is a good way to test whether particular file, having a timestamp in the name is created?

   def writeFileOnDisk(fileName: Sting, outpuPath: String ): Unit = {
 
      val saveFileNamePth = outputPath + fileName + "_" + currentTimestamp
      // write the file on the disk 

    }

The method basically writes file on the disk with a timestamp in the name, up to seconds("YYYYMMddhhmmss").

Ideas so far are for regex for the particular day or create an empty directory and check if a file is created.

The goals is to assert whether the file in the particular time is created.

Any suggestions?

3
  • 1
    In a unit test, you should mock away the file system, and preferably also mock away the system time, so that the operation is fast and 100% deterministic. Jun 19, 2020 at 7:52
  • 3
    Such a test would essentially be useless. Jun 19, 2020 at 12:03
  • 1
    Dear down-voters, please leave a criticism along with your vote. I do not see the problem with this Question. Jun 21, 2020 at 5:52

2 Answers 2

1

Clock

As for the issue of getting a timestamp, use the java.time classes.

Capture the current moment as seen in UTC.

Instant instant = Instant.now() ;

To get a fake time, pass a Clock object.

The Clock class has methods that offer variants with special behaviors, ideal for testing. Those behaviors include being stuck at a certain moment, being offset from the true time yet incrementing forward in time, and altered cadence such as incrementing only by a full minute at a time. To explicitly use the normal default Clock, call Clock.systemUTC() as discussed here.

Here we specify the moment of noon on a certain date in a certain zone. For this we want to use Clock.fixed.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
LocalDate ld = LocalDate.of( 2021 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.NOON ; 
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

Adjust to UTC. Same moment, same point on the timeline, different wall-clock time.

Instant instant = zdt.toInstant() ;

Make the fake.

Clock clock = Clock.fixed( instant , z ) ;

Use the fake.

Instant instantFake = Instant.now( clock ) ;

instantFake.toString(): 2021-01-23T03:00:00Z

Time in Asia/Tokyo is nine hours ahead of UTC at that moment. So this result makes sense. Going nine hours back from noon there is 3 AM in UTC ( 12-9 = 3 ).

ISO 8601 Basic format

Produce a String with text in standard ISO 8601 format. The Z you see on the end means UTC and is pronounced “Zulu”.

String output = instantFake.toString() ;

The format you desire is nearly compliant with the “basic” variant allowed in ISO 8601. Two differences:

  • A T in the middle, separating the year-month-day from the hour-minute-second.
  • A Z on the end, indicating UTC as the offset/zone.

I suggest you adopt both of those features. The first makes your string more recognizable as a date-time rather than some arbitrary identifier. The second provides a context in which to interpret the date and the time. Without a context, the reader has no way of knowing if you meant 3 AM in Tunisia, 3 AM in Toledo Ohio US, 3 AM in UTC, or 3 AM somewhere else — all different moments, several hours apart.

Define a DateTimeFormatter with a custom formatting pattern. To use a custom formatter, we need to convert from the basic class Instant to the more flexible class OffsetDateTime.

OffsetDateTime odt = instantFake.atOffset( ZoneOffset.UTC ) ;

Define our custom formatting pattern.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmssX" );
String output = odt.format( f );

20210123T030000Z

And use that formatter to parse such strings back into OffsetDateTime object, and extract a Instant.

Instant instantReplay = OffsetDateTime.parse( output , f ).toInstant();

Table of all date-time types in Java, both modern and legacy


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

5

Ideally, in a unittest environment both the file system and the time are mocked. Then your test has full control over what time it is and you can easily verify what actions the code-under-test tries to do towards the filesystem.

If the filesystem can't be mocked, then you need to determine a safe location where your test can write and check that a file with the expected filename was created there.

If the time can't be mocked, then the safest approach for this kind of test is to determine the current time at the start and the end of the test. The created filename should contain a timestamp from that interval.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.