简体   繁体   English

Jest:测试是否调用了 addEventListener 的回调函数

[英]Jest: test if callback function from addEventListener was called

I have next functions:我有下一个功能:

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)
    },
  }
}

In my Jest test, I want to check, if hashChangeCallback function was called when event was triggered:在我的 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
  })
})

How to do it properly?如何正确操作? Do I have to mock/spy on this function somehow?我是否必须以某种方式模拟/监视此功能?

If the hashChangeCallback function is not exported, you can't mock or spy it.如果未导出hashChangeCallback函数,则无法模拟或监视它。 You can indirectly assert whether hashChangeCallback is called by asserting whether console.log is called.您可以通过断言是否调用console.log来间接断言hashChangeCallback是否被调用。

Besides, it should be event.oldURL rather than event.oldUrl .此外,它应该是event.oldURL而不是event.oldUrl

Eg例如

urlHashChangeListener.ts : 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 : 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();
  });
});

test result:测试结果:

 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

package versions:包版本:

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

You could generalise your functions to make your testing a little easier and reduce duplication:您可以概括您的功能,使您的测试更容易一些并减少重复:

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([...])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM