开玩笑模拟 IntersectionObserver

Jest Mock IntersectionObserver

我有以下方法:

componentDidLoad() {
    this.image = this.element.shadowRoot.querySelector('.lazy-img');
    this.observeImage();
  }

observeImage = () => {
    if ('IntersectionObserver' in window) {
      const options = {
        rootMargin: '0px',
        threshold: 0.1
      };

      this.observer = new window.IntersectionObserver(
        this.handleIntersection,
        options
      );

      this.observer.observe(this.image);
    } else {
      this.image.src = this.src;
    }
  };

我试图测试 IntersectionObserver.observe 这样的调用:

it('should create an observer if IntersectionObserver is available', async () => {
    await newSpecPage({
      components: [UIImageComponent],
      html: `<ui-image alt="Lorem ipsum dolor sit amet" src="http://image.example.com"></ui-image>`
    });

    const mockObserveFn = () => {
      return {
        observe: jest.fn(),
        unobserve: jest.fn()
      };
    };

    window.IntersectionObserver = jest
      .fn()
      .mockImplementation(mockObserveFn);

    const imageComponent = new UIImageComponent();
    imageComponent.src = 'http://image.example.com';

    const mockImg = document.createElement('img');
    mockImg.setAttribute('src', null);
    mockImg.setAttribute('class', 'lazy-img');

    imageComponent.element.shadowRoot['querySelector'] = jest.fn(() => {
      return mockImg;
    });
    expect(imageComponent.image).toBeNull();
    imageComponent.componentDidLoad();

    expect(mockObserveFn['observe']).toHaveBeenCalled();
  });

但是打不开,我的mockObserveFn.observe还没有接到电话,有什么建议

你的mockObserveFn.observe没有被调用,因为它不存在。

您可能遇到以下错误:

Matcher error: received value must be a mock or spy function

你可以像这样定义你的 mock

const observe = jest.fn();
const unobserve = jest.fn();

// you can also pass the mock implementation
// to jest.fn as an argument
window.IntersectionObserver = jest.fn(() => ({
  observe,
  unobserve,
}))

然后你可以期待:

expect(observe).toHaveBeenCalled();

这个解决方案适合我。

基本上你只需将 Intersection Mock 放在 beforeEach

beforeEach(() => {
  // IntersectionObserver isn't available in test environment
  const mockIntersectionObserver = jest.fn();
  mockIntersectionObserver.mockReturnValue({
    observe: () => null,
    unobserve: () => null,
    disconnect: () => null
  });
  window.IntersectionObserver = mockIntersectionObserver;
});