Search code examples
scalamockitojava-timespecs2localdatetime

Is there a way to mock LocalDateTime timestamp using specs


I am supposedly contributing to the integration tests of a library which relies on specs with the underlying implementation written in Scala. The testing is more bind towards the stream of events flowing with some timestamp attribute.

The following stub is the part of the actual implementation

private def eligibleForRecentPost(optionalPost: Option[SearchEntity]): Boolean = {
    optionalSearch.map(search => search.timestamp)
      .exists(searchTime => searchTime >= LocalDateTime.now()
        .minusDays(recencyDurationInDays).atZone(ZoneId.systemDefault).toInstant.toEpochMilli)
}

Now, the code that I would look for might be something like

// just a mock
when(LocalDateTime.now().minusDays(any)
    .atZone(ZoneId.systemDefault).toInstant.toEpochMilli)
    .thenReturn(1579625874972)

Note, I am aware that the search.timestamp in the test could be updated, but that would require updating the events after every recencyDurationInDays!!

But is there a better and reliable way to do this in specs2 and/or scala?

Edit: I must mention that I am not looking forward to changing the implementation such that the LocalDateTime is overridden/wrapped with another class.


Solution

  • There are tools like powermock which allows such things. But they are last resort solution, if you have to mock something in code that you have no control over.

    Normally you would instead do something like:

    trait Clock {
    
      def now(): LocalDateTime  
    }
    
    class DefaultClock extends Clock {
    
      def now(): LocalDateTime = LocalDateTime.now()
    }
    

    and then inject Clock instance into the code that uses it.

    Instead of mocking static method you could just pass an instance that does whatever you wanted:

    val simulatedNow = ... // calculate the right date for now
    val clock = new Clock {
      def now() = simulatedNow
    }
    // inject clock
    // run code and check assertion