Total results: 2

How to stub Date in Jest tests: building a `stubDate` helper

tl;dr: the stubDate helper can be copied from the bottom of the article.

It is a common case in unit testing to need a static date returned in your tests so that you can either have a fixed expectations (e.g. in a JSON), or to prevent random failures when tests are executed seconds later than when the expectations where made.

For this reason, if you are using Jest, you want to stub the Date object inside your Jest tests so that when calling new Date() or Date.now() aways returns the same result.

Jest does not provide a built in method for stubbing the JavaScript Date object so we have to do this manually. This can be done by overriding the global Date object.

const fixedDate = new Date('2018-02-28T09:39:59');

Date = class extends Date {
  constructor() {
    super();

    return fixedDate;
  }
};

This is enough to get a test passing, which will always return the time "2018-02-28 09:39:59", regardless which Date methods are called. For example, calling getTime() on the date instance will always return "1519807199000".

beforeAll and afterAll

Since we are using Jest we can use the beforeAll function to set the date before all tests in a test file, so that this code does not have to be copied into each test case.

const fixedDate = new Date('2018-02-28T09:39:59');

beforeAll(() => {
  Date = class extends Date {
    constructor() {
      super();

      return fixedDate;
    }
  };
});

It is also important to reset Date back to the original "real" Date object after all tests have run to prevent confusing errors in future tests where you expect to work with a non-stubbed date. We can do this with a Jest afterAll function. This means we have to cache the original Date object in the beforeAll.

const fixedDate = new Date('2018-02-28T09:39:59');
let _originalDate;

beforeAll(() => {
  _originalDate = Date;

  Date = class extends Date {
    constructor() {
      super();

      return constantDate;
    }
  };
});

afterAll(() => {
  Date = _originalDate;
});

stubDate helper

Finally we can piece this all together into a handy stubDate helper than can be imported into any test file, leaving the test implementation clean of the stubbing boilerplate code. I usually use a file called test-helper.js where helper functions like this live.

// test-helper.js

export const stubDate = fixedDate => {
  let _originalDate;

  beforeAll(() => {
    _originalDate = Date;

    Date = class extends Date {
      constructor() {
        super();

        return fixedDate;
      }
    };
  });

  afterAll(() => {
    Date = _originalDate;
  });
};

This can then be imported into a test file and the before and after actions will automatically be applied to your tests. For example:

// my-spec.js

import { stubDate } from './test-helper';

it('can stub the global date object', () => {
  const myDate = new Date('2018-02-28T09:39:59');

  stubDate(myDate);

  // This expectation will always pass regardless of what time the test is run
  expect(Date.now()).toEqual(1519807199000);
});

Building a PDF Library with Gatsby.js

Like most developers I have large libraries of PDF books lying around in a folder somewhere. In order to organise the books and get a better overview I decided to work on a weekend project designed to investigate Gatsby.js, a React / GraphQL based static site generator. The project was to use Gatsby to build a PDF library that would allow me to put my PDF books into the project and then build a simple static website that would list the PDFs, give some information about each book, allow me to read them online, and finally download them if I wanted.

Demo

My static Gatsby based PDF library ended up with the following features:

  • List view of PDF books, read from the file system
  • Metadata extraction from the PDF book (Author, Page count, etc.)
  • Read a book online
  • "Fullscreen" reading mode
  • Download a book
  • Remember your page number, for future reading
  • Search for books

You can see a demo of the Library here: https://blakesimpson.github.io/gatsby-library/

What is Gatsby?

Gatsby

As mentioned in the introduction, Gatsby.js is a static site generator built with JavaScript. Gatsby uses React for building the views and a GraphQL API that is queried from your views to read information about your static files.

This means you can add, for example, a bunch of Markdown files to your project and Gatsby will run through each file (what it calls a "node") to index these and put them into the GraphQL index. You can then build a list of your Markdown articles to the home page and link to each one and render it as a web page.

With this setup, Gatsby is very good for building static websites that do not rely on a database at runtime, for example, a blog.

However, Gatsby can not only read Markdown files from your system, it can read any file type such as an Excel spreadsheet, or as I discovered, a PDF.

Before going on to show how I extracted PDF information and put it into the Gatsby index you might want to try out some Gatsby starter examples such as the gatsby-blog.

Also, if you have never worked with Gatsby before, it is a good idea to work through the tutorial which helps to understand the Gatsby concepts such as configuration, the node server, and how the plugins work.

© Blake Simpson, 2012 – 2018