How to mock/test IntersectionObserver using JEST

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport-Mozila

Let’s write a simple javascript function that writes the value to the console based on the intersectionRatio value. The Intersection Observer API updates this value when certain conditions are met.

const TestModule = () => {
  const options = {
    root: null, // use null for viewport
    rootMargin: "0px",
    threshold: 1.0,
  };
  const _callback = (entries, observer) => {
    if (entries.intersectionRatio > 1) {
      console.log("do something");
    } else {
      console.info("do something else");
    }
  };
  const init = () => {
    const observer = new IntersectionObserver(_callback, options);
    const target = document.querySelector("#someSection");
    observer.observe(target);
  };
  const obj = {
    init,
  };
  return obj;
};
module.exports = TestModule;

Solution

const TestModule = require("../module")();
describe("IntersectionObserver", () => {
  it("should  call console.log", () => {
    const mockedEntries = [
      {
        isIntersecting: true,
        boundingClientRect: { x: 10, y: 20, width: 30, height: 40 },
      },
    ];
    const observe = jest.fn();
    const unobserve = jest.fn();
    window.IntersectionObserver = jest.fn(() => ({
      observe,
      unobserve
    }));
    jest.spyOn(document, "querySelector").mockReturnValueOnce(mockedEntries);
    const consoleLogSpy=jest.spyOn(console,"log");
    TestModule.init();
    let [callback] = window.IntersectionObserver.mock.calls[0];
    expect(observe).toBeCalledTimes(1);
    callback({
      isIntersecting: false,
      intersectionRatio: 10,
    });
    expect(consoleLogSpy).toBeCalledTimes(1);
  });
  it("should  call console.info", () => {
    const mockedEntries = [
      {
        isIntersecting: true,
        boundingClientRect: { x: 10, y: 20, width: 30, height: 40 },
      },
    ];
    const observe = jest.fn();
    const unobserve = jest.fn();
    window.IntersectionObserver = jest.fn(() => ({
      observe,
      unobserve
    }));
    jest.spyOn(document, "querySelector").mockReturnValueOnce(mockedEntries);
    const consoleInfoSpy=jest.spyOn(console,"info");
    TestModule.init();
    let [callback] = window.IntersectionObserver.mock.calls[0];
    expect(observe).toBeCalledTimes(1);
    callback({
      isIntersecting: false,
      intersectionRatio: 1,
    });
    expect(consoleInfoSpy).toBeCalledTimes(1);
  });
});
PASS  __tests__/module.test.js
  IntersectionObserver
    √ should  call console.log (30 ms)
    √ should  call console.info (3 ms)

-----------|---------|----------|---------|---------|------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s

-----------|---------|----------|---------|---------|------------------
All files  |     100 |      100 |     100 |     100 |

 module.js |     100 |      100 |     100 |     100 |
-----------|---------|----------|---------|---------|------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.266 s
Ran all test suites.

This code is taken from my book Test Driven Development Using JavaScript and Jest

Please do not post any spam link in the comment box😊

Post a Comment (0)
Previous Post Next Post