Home > Net >  How to Mock LocalDate.now() in Scala
How to Mock LocalDate.now() in Scala

Time:01-25

I have object

object func1{
   def something(arg1: Int): String{
    // var date = something2()
    // Using date
   }

   def something2(): LocalDate{
      LocalDate.now()
    }
}
  

I want to write a test on something method, How can I mock something2

CodePudding user response:

You can't make static methods. So, you need to do something like this:

def something(val now: () => Date = LocalDate.now) = ...

Then, in your production code, you do val foo = something() as you normally would, but in your test, you can do things like

something(_ => new Date(0l)) shouldBe foo

or

val date = mock[Function0[Date]]
when(date.apply()).thenReturn(new Date(0l))
something(date) shouldBe foo

CodePudding user response:

If the code's functionality depends on the time, it's definitely recommended that you have a second look at the code you're testing and explicitly pass a Clock as a parameter or something along those lines (e.g. a function as suggested in other comments) to make its behavior easy to test.

If you are testing this to make sure that a field somewhere indeed contains the time returned by LocalDate.now() please consider that you might be testing the behavior of LocalDate rather than your own code's, so probably mocking that doesn't really give you anything.

If timing is fundamental to the function's behavior and you have no control over it, I believe you might somehow use Mockito's ability to mock static objects. I came up with the following which compiles, but I'm not sure about whether it works or not (since I believe it relies on some bytecode manipulation black magic which might make your testing suite brittle, so beware):

import scala.util.{Try, Using}
import java.time.{Clock, Instant, LocalDate, ZoneId}
import org.mockito.Mockito._

def withClock[A](clock: Clock)(f: => Unit): Try[Unit] = {
  Using(mockStatic(classOf[LocalDate])) { mocked =>
    mocked.when(() => LocalDate.now()).thenReturn(LocalDate.now(clock))
    f
  }
}

withClock(Clock.fixed(Instant.ofEpochMilli(42), ZoneId.of("UTC"))) {
  assert(LocalDate.now().toEpochDay() == 0)
}
  • Related