开玩笑:测试是否调用了addEventListener的回调函数

时间:2020-08-27 09:41:44

标签: javascript jestjs enzyme

我有下一个功能:

const hashChangeCallback = event => {
   console.log('event', event.oldUrl)
}

const hashHandler = () => {
  return {
    add: () => {
      window.addEventListener('hashchange', (event) => hashChangeCallback(event), false)
    },
    remove: () => {
      window.removeEventListener('hashchange', (event) => hashChangeCallback(event), false)
    },
  }
}

在Jest测试中,我想检查触发事件时是否调用了hashChangeCallback函数:

import { hashHandler } from './urlHashChangeListener'

describe('urlHashChangeListener', () => {
  const setupHashListeners = hashHandler()


  it('hashChangeCallback should be called when hash changed if listener is added', () => {
    setupHashListeners.add()

    window.dispatchEvent(new HashChangeEvent('hashchange', {
      oldURL: 'http://test.com/test.html#hash123', 
      newURL: 'http://test.com/test.html#hash3'
    }))

    // expect hashChangeCallback to be called
  })
})

如何正确执行?我是否必须以某种方式模拟/监视此功能?

2 个答案:

答案 0 :(得分:0)

如果 hashChangeCallback 函数未导出,则无法模拟或窥探它。您可以通过断言 hashChangeCallback 是否被调用来间接断言 console.log 是否被调用。

此外,它应该是 event.oldURL 而不是 event.oldUrl

例如

urlHashChangeListener.ts

const hashChangeCallback = (event) => {
  console.log('event', event.oldURL);
};

export const hashHandler = () => {
  return {
    add: () => {
      window.addEventListener('hashchange', (event) => hashChangeCallback(event), false);
    },
    remove: () => {
      window.removeEventListener('hashchange', (event) => hashChangeCallback(event), false);
    },
  };
};

urlHashChangeListener.test.ts

import { hashHandler } from './urlHashChangeListener';

describe('urlHashChangeListener', () => {
  const setupHashListeners = hashHandler();

  it('hashChangeCallback should be called when hash changed if listener is added', () => {
    const logSpy = jest.spyOn(console, 'log');
    setupHashListeners.add();

    window.dispatchEvent(
      new HashChangeEvent('hashchange', {
        oldURL: 'http://test.com/test.html#hash123',
        newURL: 'http://test.com/test.html#hash3',
      })
    );

    expect(logSpy).toBeCalledWith('event', 'http://test.com/test.html#hash123');
    logSpy.mockRestore();
  });
});

测试结果:

 PASS  examples/63613274/urlHashChangeListener.test.ts (7.068 s)
  urlHashChangeListener
    ✓ hashChangeCallback should be called when hash changed if listener is added (17 ms)

  console.log
    event http://test.com/test.html#hash123

      at console.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        7.745 s, estimated 8 s

包版本:

"enzyme": "^3.11.0",
"jest": "^26.6.3"

答案 1 :(得分:0)

你可以概括你的函数,让你的测试更容易一些并减少重复:

const controlListener = event => fn => ({
    add: () => window.addEventListener(event, fn, false),
    remove: () => window.removeEventListener(event, fn, false),
  })

export const hashListener = controlListener('hashchange')

// In your production code
const hashHandler = hashListener(hashChangeCallback)

// In your test file
const mockHashChangeCallback = jest.fn()
const hashHandler = hashListener(mockHashChangeCallback)
expect(mockHashChangeCallback.mock.calls).toEqual([...])