How to mock current time in elixir

I have some tests which depends on current time and am not able to find a solution for it so far. I have tried some mocking libraries like mock but it mocks the whole module and it fails. Any help will be really appreciated(if I only mock DateTime.utc_now everything is ok)

Note: tests depends heavily on other DateTime and Date functions so mocking whole modules is not a very good option(I have tried this also but failed due to very complex cases and I need this in many tests)

Actual test: I have two dates, start date and end date as input to a function which I am trying to test. Before calling the function for test purpose I insert some data relevent to the current week(current dat to next seven days). Now the function will get current datetime and check for specific days(each record will tell if it applies to current day of the week and for current time period range on which being iterated -> start and end dates).
e.g one record applies for mon -> 2:12 to 3:13

Is it possible for you to make the current time an argument into the function, just like start date and end date? Then you probably wouldn’t need to mock it.

2 Likes

Its possible(not very good option but yes) and I think the only solution (but it will fail in some cases e.g controllers shouldn’t send current date as option to this context method. but for testing context itself it will work)

Or define your own function/service MyDateTime.utc_now/0 and mock it in your tests.

6 Likes

not very good option but yes
but it will fail in some cases e.g controllers shouldn’t send current date as option to this context method.

Some other function in your context can do that.

# in controller
def post(conn, params) do
  # ...
  Context.do_stuff(with: command)
  # ...
end

# in your context
def do_stuff(with: %Command{...} = command) do
  do_stuff(with: command, time: DateTime.utc_now())
end

# false, since it's used directly only in tests
@doc false
def do_stuff(with: command, time: time) do # this is what you test
  # ... your logic
end
4 Likes

Thank you sooo much @idi527 for giving me great options. But @nresni 's answer suits best for my needs.

1 Like