简体   繁体   中英

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). eg one record applies for mon -> 2:12 to 3:13

The solution which best suits my needs(simple, works well and according to the requirements described above) is:

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

NB this answer is obsoleted since Elixir v1.8 Now the default parameters are not evaluated at compile time. Credits @HentikN.

Now the function will get current datetime and check for specific days [...]

This is where the real issue sits. You made your function not pure for no reason. Usually the purity means the function has no side effects, but blindly changing the outcome depending on the outside world does not sound as a robust approach either.

That said, you should make this function to accept a parameter now or like (it might be defaulted to now for the sake of brevity):

- def my_func(param) do
+ def my_func(param, dt \\ nil) do
+   dt = if is_nil(dt), do: DateTime.utc_now(), else: dt

(Naïve dt \\\\ DateTime.utc_now() won't work because function heads are evaluated at the compile time .)

Now in your tests you might call this function passing the time you want and (which is even more important) your function is not a blackbox depending on the unrelated conditions from the outside anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM