kotlinx-datetime icon indicating copy to clipboard operation
kotlinx-datetime copied to clipboard

Implement mock TimeMark for consistent testing

Open r8vnhill opened this issue 2 years ago • 1 comments

Hi team,

I'd like to propose the implementation of mock TimeMark objects in kotlinx.datetime. This would greatly enhance our testing capabilities, especially for functions that heavily rely on TimeMark objects.

Use Cases:

  • Consistent Testing: Having the ability to create mock TimeMarks will allow us to perform more consistent unit tests. Currently, tests that depend on TimeMark objects are subject to variation due to the real-time nature of these objects. Mock TimeMarks would remove this uncertainty and provide a reliable baseline for testing.

  • Time-Sensitive Logic: For applications that have time-sensitive logic, being able to control and manipulate TimeMarks will be invaluable for thorough testing. This is especially crucial for applications that have complex behaviours based on specific timing sequences.

  • Reproducible Scenarios: Mock TimeMarks will enable developers to create reproducible test scenarios. This will allow more accurate bug replication and tracking.

Proposed Syntax:

Here's a possible syntax for creating mock TimeMarks:

// Create a mock TimeMark at a specific point in time
// (year, month, dayOfMonth, hour, minute, second, nanosecond, timeZone)
val mockTimeMark = TimeMark.mock(
  year = 2021, month = 1, dayOfMonth = 1, 
  hour = 0, minute = 0, second = 0, nanosecond = 0,
  timeZone = TimeZone.UTC)
// (epochMilliseconds, timeZone)
val mockTimeMark = TimeMark.mock(
  epochMilliseconds = 1609459200000L,
  timeZone = TimeZone.UTC)

In this scenario, the TimeMark object will be created at the specified point in time: 2021-01-01T00:00:00.000Z. The first syntax consists of a TimeMark.mock() function that takes in the year, month, dayOfMonth, hour, minute, second, nanosecond, and timeZone as parameters; default values should be provided for all parameters, although the optionality of the time zone parameter can be discussed. The second syntax consists of a TimeMark.mock() function that takes in the milliseconds since the Unix epoch and the time zone as parameters; the optionality of both parameters can be discussed.

Thank you for considering this suggestion. I believe it will bring significant improvements to the kotlinx.datetime library and its usability in testing scenarios.

Best Regards

r8vnhill avatar Jul 28 '23 22:07 r8vnhill

The use case when it's needed to create time marks this way is not completely clear to me.

Have you considered the alternatives?

  • Kotlin standard library provides TestTimeSource class which allows to advance time manually in test scenarios
  • if you need an Instant-based time mark, you can obtain it from a time source returned by Clock.asTimeSource() function. The Clock interface is trivial to implement and you can control the current moment in your Clock implementation as you want.

ilya-g avatar Sep 01 '23 04:09 ilya-g