Jest Mock IntersectionObserver

Jea*_*ean 6 mocking jestjs stenciljs

我有以下方法:

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

我试图像这样测试 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();
  });
Run Code Online (Sandbox Code Playgroud)

但不能让它工作,我的 mockObserveFn.observe 没有被调用,任何建议

Yud*_*ndi 18

这个解决方案对我有用。

基本上你只需将 IntersectionMock 放入 beforeEach 中

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


Ten*_*eff 14

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

可能您收到以下错误:

Matcher error: received value must be a mock or spy function
Run Code Online (Sandbox Code Playgroud)

你可以像这样定义你的模拟

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

然后你可以期待:

expect(observe).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)