来自 Jest 中 Intersection Observer 的模拟“isIntersecting”

mai*_*idi 5 jestjs intersection-observer

我有一个使用相交观察器的组件,并且想开玩笑地测试元素相交时的效果。我已经成功地模拟了交叉口观察者,就像这个答案一样:/sf/answers/4105615461/

现在我想在特定元素上“假回调” isIntersecting 触发器。可以在测试中模拟这个吗?

 const observe = jest.fn();
 const disconnect = jest.fn();
 setupIntersectionObserverMock({ observe: observe, disconnect: disconnect });
 const page = await newSpecPage({
   components: [TestComponent],
   html: `<div></div>`, // This is the element I want to trigger an "isIntersecting" on 
 });

export const 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,
  });
};
Run Code Online (Sandbox Code Playgroud)

Lot*_*tus 3

对的,这是可能的。您需要做 2 处更改:

takeRecords触发时返回每个条目的值observe

这意味着您需要通过将其放入setupIntersectionObserverMock或默认属性来更改 takeRecords:

export function setupIntersectionObserverMock({
  root = null,
  rootMargin = '',
  thresholds = [],
  disconnect = () => null,
  observe = () => null,
  takeRecords = () => [
    {
      boundingClientRect: {} as DOMRectReadOnly,
      intersectionRatio: 1,
      intersectionRect: {} as DOMRectReadOnly,
      isIntersecting: true,
      rootBounds: null,
      target: {} as Element,
      time: 1,
    },
  ],
  unobserve = () => null,
} = {}): void {
Run Code Online (Sandbox Code Playgroud)

第二步是处理 IntersectionObserver 构造函数回调:

constructor(callback: (entries: IntersectionObserverEntry[], observer: IntersectionObserver) => void) {
  callback(takeRecords(), this);
}
Run Code Online (Sandbox Code Playgroud)

整个代码如下:

export function setupIntersectionObserverMock({
  root = null,
  rootMargin = '',
  thresholds = [],
  disconnect = () => null,
  observe = () => null,
  takeRecords = () => [
    {
      boundingClientRect: {} as DOMRectReadOnly,
      intersectionRatio: 1,
      intersectionRect: {} as DOMRectReadOnly,
      isIntersecting: true,
      rootBounds: null,
      target: {} as Element,
      time: 1,
    },
  ],
  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;

    constructor(callback: (entries: IntersectionObserverEntry[], observer: IntersectionObserver) => void) {
      callback(takeRecords(), this);
    }
  }

  Object.defineProperty(window, 'IntersectionObserver', {
    writable: true,
    configurable: true,
    value: MockIntersectionObserver,
  });

  Object.defineProperty(global, 'IntersectionObserver', {
    writable: true,
    configurable: true,
    value: MockIntersectionObserver,
  });
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

2338 次

最近记录:

3 年,12 月 前