kotlinmockk

How to mock Instant.now() in Kotlin?


How can I mock Instant.now() using mockK? This code throws error:

@Test
fun testStaticMock() {
  val instant = Instant.parse("2024-03-22T12:00:00.000Z")
  mockkStatic(Instant::class) {
    every { Instant.now() } returns instant
    val actual = Instant.now()
    assertEquals(instant, actual)
  }
}

Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock


Solution

  • Not really answering your question here, but that's because I think it is bad practice to mock an Instant. You should instead use a Clock and pass it as an argument to your service/function. You can call Instant.now(clock) to get an instant from the Clock. A Clock makes your code much more testable, because you can control it better from your tests.

    In your production code, you can use a real clock with Clock.system(ZoneId zone), Clock.systemDefault() or Clock.systemUTC().

    In your tests, you can create a fixed-clock with Clock.fixed(Instant fixedInstant, ZoneId zone), and even make it tick with Clock.tick, Clock.tickMinutes or Clock.tickSeconds. This will make your tests more predictable, because they won't depend on the time they are run.