DEV Community

Cover image for How to Mock Luxon's DateTime.now When Using TDD
Alex Kates
Alex Kates

Posted on • Edited on • Originally published at alexkates.dev

How to Mock Luxon's DateTime.now When Using TDD

When is this relevant?

Ok, here's the situation. You are maintaining a NodeJS application that depends on Luxon and you practice test-driven development. Along comes a requirement that is dependent on the current date and time.

If you tried to use Luxon's default DateTime.now() function in your tests, you will quickly find that it's difficult to set up proper test data and assertions. This is due to the coupling between the tests and the actual current time.

What's the solution?

As TDD practitioners, we know it's always a good thing to fake integration points. This is true for network calls, database read/writes, and even the system clock!

Let's dive deeper into how you can leverage Jest to fake Luxon's default DateTime.now() function so we can assert on an expected current time.

First, let's take a look at a very simple system under test (SUT).

import { DateTime } from 'luxon';

export const doSomethingThatDependsOnDateTimeNow = () => DateTime.now();
Enter fullscreen mode Exit fullscreen mode

Nothing special here, just a simple function that returns Luxon's DateTime.now() result.

Now let's dive into the unit test.

import { DateTime, Settings } from 'luxon';
import { doSomethingThatDependsOnDateTimeNow } from './doSomethingThatDependsOnDateTimeNow';

describe('Mocking DateTime.now with Luxon', () => {
  it('should return the mock DateTime', () => {
    // Arrange
    const expectedNow = DateTime.local(2021, 6, 1, 23, 0, 0);
    Settings.now = () => expectedNow.toMillis();

    // Act 
    const actual = doSomethingThatDependsOnDateTimeNow();

    // Assert
    expect(actual).toEqual(expectedNow);
  });
});
Enter fullscreen mode Exit fullscreen mode

A lot going on here, so let's break it down.

First, we need to import Settings from Luxon, which is used to configure Luxon. We also import DateTime and our system under test (SUT), doSomethingThatDependsOnDateTimeNow.

Next, in the arrange section of the test, we create a new DateTime for the date 6/1/2021 at 11 pm EST. Then we override the DateTime.Now() function by assigning a new function Settings.now that returns our DateTime instead of the current time.

Finally, we invoke our SUT, capture the actual result, and assert that it is equal to our DateTime value.

Wrapping things up

Using TDD and integrating with Luxon's DateTime.now() can be a bit complex at first, but I hope this guide helps you red-green-refactor your way through your next time-based application feature.

If you found this useful, please consider following me on Twitter https://twitter.com/thealexkates

Top comments (2)

Collapse
 
jaypitroda profile image
Jay Pitroda

Thank you for this post!

Collapse
 
grenguar profile image
Igor Soroka

Very helpful post! Thanks a lot!