JS - Testing code that uses an IntersectionObserver

前端 未结 6 1659
死守一世寂寞
死守一世寂寞 2020-12-18 17:57

I have a (rather poorly written) javascript component in my application that handles infinite scroll pagination, and i\'m trying to rewrite it to use the IntersectionO

6条回答
  •  感动是毒
    2020-12-18 18:57

    Here's another alternative based on previous answers, you can run it inside the beforeEach methods, or at the beginning of the .test.js file.

    You could also pass parameters to the setupIntersectionObserverMock to mock the observe and/or unobserve methods to spy on them with a jest.fn() mock function.

    /**
     * Utility function that mocks the `IntersectionObserver` API. Necessary for components that rely
     * on it, otherwise the tests will crash. Recommended to execute inside `beforeEach`.
     * @param intersectionObserverMock - Parameter that is sent to the `Object.defineProperty`
     * overwrite method. `jest.fn()` mock functions can be passed here if the goal is to not only
     * mock the intersection observer, but its methods.
     */
    export function setupIntersectionObserverMock({
      root = null,
      rootMargin = '',
      thresholds = [],
      disconnect = () => null,
      observe = () => null,
      takeRecords = () => null,
      unobserve = () => null,
    } = {}) {
      class MockIntersectionObserver {
        constructor() {
          this.root = root;
          this.rootMargin = rootMargin;
          this.thresholds = thresholds;
          this.disconnect = disconnect;
          this.observe = observe;
          this.takeRecords = takeRecords;
          this.unobserve = unobserve;
        }
      }
    
      Object.defineProperty(window, 'IntersectionObserver', {
        writable: true,
        configurable: true,
        value: MockIntersectionObserver
      });
    
      Object.defineProperty(global, 'IntersectionObserver', {
        writable: true,
        configurable: true,
        value: MockIntersectionObserver
      });
    }
    

    And for TypeScript:

    /**
     * Utility function that mocks the `IntersectionObserver` API. Necessary for components that rely
     * on it, otherwise the tests will crash. Recommended to execute inside `beforeEach`.
     * @param intersectionObserverMock - Parameter that is sent to the `Object.defineProperty`
     * overwrite method. `jest.fn()` mock functions can be passed here if the goal is to not only
     * mock the intersection observer, but its methods.
     */
    export function setupIntersectionObserverMock({
      root = null,
      rootMargin = '',
      thresholds = [],
      disconnect = () => null,
      observe = () => null,
      takeRecords = () => null,
      unobserve = () => null,
    } = {}): void {
      class MockIntersectionObserver implements IntersectionObserver {
        readonly root: Element | null = root;
        readonly rootMargin: string = rootMargin;
        readonly thresholds: ReadonlyArray < number > = thresholds;
        disconnect: () => void = disconnect;
        observe: (target: Element) => void = observe;
        takeRecords: () => IntersectionObserverEntry[] = takeRecords;
        unobserve: (target: Element) => void = unobserve;
      }
    
      Object.defineProperty(
        window,
        'IntersectionObserver', {
          writable: true,
          configurable: true,
          value: MockIntersectionObserver
        }
      );
    
      Object.defineProperty(
        global,
        'IntersectionObserver', {
          writable: true,
          configurable: true,
          value: MockIntersectionObserver
        }
      );
    }
    

提交回复
热议问题