Back to Blog

MERN Jest Testing (Part 7)

Wajiha Niazi

Global functions

Global methods are functions that are available to any script as they are not methods of any specific object. You can invoke global methods directly just as you would do with any core JavaScript global functions.

Jest puts each of these methods and objects into the global environment. You don't have to require or import anything to use them. However, if you prefer explicit imports, you can do import {describe, expect, it} from '@jest/globals'.

When's defining your global function these are some of the options you can/have to include:

  • describe(name, fn) A describe block is used for organizing test cases in logical groups of tests. The first argument is a string that defines what kind of test we want to write in the block and the second argument is a callback function for wrapping the actual test.
  • This isn't required - you can write the test blocks directly at the top level.
  • You can also nest describe blocks if you have a hierarchy of tests.
  • test(name, fn, timeout)  The first argument is a string that defines what we want to do in the test and the second argument is a function containing our expectations. If the test return a promise Jest will wait to resolve the promise before completing the test.
  • it(name, fn, timeout) It is the alias of test().
  • beforeAll(fn, timeout)Runs a function before any of the tests in this file run. If the function returns a promise asynchronously or is a generator, Jest waits for that promise to resolve before running tests.
  • This is often useful if you want to set up some global state that will be used by many tests.
  • If beforeAll is inside a describe block, it runs at the beginning of the describe block.
  • If you want to run something before every test instead of before any test runs, use beforeEach instead. This is often useful if you want to reset some global state that will be used by many tests.
  • afterAll(fn, timeout)Runs a function after all the tests in this file have been completed. If the function returns a promise asynchronously or is a generator, Jest waits for that promise to resolve before continuing.
  • This is often useful if you want to clean up some global setup state that is shared across tests.
  • If afterAll is inside a describe block, it runs at the end of the describe block.
  • If you want to run some cleanup after every test instead of after all tests, use afterEach instead. This is often useful if you want to clean up some temporary state that is created by each test.

NOTE: The timeout (in milliseconds) argument is optional and specifies how long to wait before aborting. the default timeout is 5 seconds.

Example :

In this example, we are going to test /blogs endpoint. Sending a GET request to /blogs returns list of blogs.

tests/routes/blog.test.js


const request = require("supertest");
const moment = require('moment');
const { ObjectId } = require('mongoose').Types;

const BlogStatusEnum = require('../../enums/BlogStatus.enum');

const app = require("../../server");
const { BlogModel } = require("../../models");

let blog;
describe("Test blogs routes", () => {
  const server = request(app);

  beforeAll(async () => {
    blog = await BlogModel.create({
        title: "Jest testing doc",
        tags: [ "informtional" ],
        description: "something....",
        cover_url: "https://www.test.com",
        createdBy: ObjectId('5dcd00cfa7d6d81dd64fc552'),
        status: BlogStatusEnum.ACTIVE,
        reactions: {
            likes: [ ObjectId('5dcd00cfa7d6d81dd64fc553') ],
            dislikes: [ ObjectId('5dcd00cfa7d6d81dd64fc554') ],
        },
        createdAt: moment().toJSON(),
    });
  });
    
  afterAll(async () => {
    await BlogModel.deleteMany();
  });

  describe("GET /Blogs", () => {
      it("should return list of blog", async () => {
        const result = await server.get("/blogs");
        expect(result.body.data[0].title).toBe(blog.title);
        expect(result.body.data[0].tags[0]).toBe(blog.tags[0]);
        expect(result.body.data[0].cover_url).toBe(blog.cover_url);
        expect(result.body.data[0].status).toBe(blog.status);
        expect(result.body.data[0].status).toBe(blog.status);
        expect(result.body.data[0].totalLikes).toBe(1);
        expect(result.body.data[0].totalDislikes).toBe(1);
    });
  });
});

In the above code,

  1. We imported the packages, Enums, and models which are needed in our test. We have imported supertest for the testing endpoint and we have imported the moment,  ObjectId, BlogStatusEnum and BlogModel for creating blogs in our test.
  2. We have describe block in our test file to group our tests,  then we have the nest describe block, in this describe block we have the actual test function, we use it() to expect the result.
  3. We have beforeAll block which creates a blog before all test starts running, and we have afterAll block which delete all blogs form DB after the completion the test.

Share on social media: