簡體   English   中英

在 Jest 中測試回調函數

[英]Testing a callback function in Jest

不用說,該應用程序比這復雜得多,但要點是相同的。 我無法對應用程序進行重大更改,例如導入/導出 onSuccess 函數或更改為基於類的組件。

單擊按鈕會啟動 Login 函數,我在其中傳入 onSuccess 函數。 我想監視分析函數以確保它被調用,但在我的測試中我無法調用 onSuccess 函數

理想情況下,我想做這樣的事情:

test("analyze should be called", () => {
  let analyzeSpy = jest.spyOn(Analytics, "analyze");
  onSuccess() //<- cannot do this
  expect(analyzeSpy).toHaveBeenCalledTimes(1);
});

這是應用程序:

import Analytics from "./Analytics";

export function Login({ onLoginSuccess }) {
  setTimeout(function () {
    console.log("TIMEOUT OVER");
    onLoginSuccess();
  }, 2000);
}

function App() {
  function handleClick() {
    console.log("Login");
    Login({
      onLoginSuccess: onSuccess,
    });
  }
  function onSuccess() {
    console.log("Login success");
    Analytics.analyze();
  }
  return (
    <>
      <button
        onClick={() => {
          handleClick();
        }}
      >
        Login
      </button>
    </>
  );
}

export default App;

這是 Analytics.js:

export default {
  analyze: () => {
    console.log("Analysis done");
  },
};

我該如何測試?

使用react-dom模塊的render()方法將您的組件渲染到js-dom提供的文檔中。

使用document.querySelector('button')獲取按鈕 dom,調度鼠標點擊事件。

使用jest.useFakeTimers()來使用標准定時器函數( setTimeout )的假版本。

分派點擊事件后,使用jest.advanceTimersByTime(2000)執行宏任務隊列(由setTimeout排隊的任務)。

然后,做一個斷言。

例如

App.jsx

import React from 'react';
import Analytics from './Analytics';

export function Login({ onLoginSuccess }) {
  setTimeout(function () {
    console.log('TIMEOUT OVER');
    onLoginSuccess();
  }, 2000);
}

function App() {
  function handleClick() {
    console.log('Login');
    Login({
      onLoginSuccess: onSuccess,
    });
  }
  function onSuccess() {
    console.log('Login success');
    Analytics.analyze();
  }
  return (
    <>
      <button
        onClick={() => {
          handleClick();
        }}
      >
        Login
      </button>
    </>
  );
}

export default App;

App.test.jsx :

import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { act } from 'react-dom/test-utils';
import App from './App';
import Analytics from './Analytics';

describe('68400320', () => {
  let container = null;
  beforeEach(() => {
    // setup a DOM element as a render target
    container = document.createElement('div');
    document.body.appendChild(container);
  });

  afterEach(() => {
    // cleanup on exiting
    unmountComponentAtNode(container);
    container.remove();
    container = null;
  });

  test('should pass', () => {
    const analyzeSpy = jest.spyOn(Analytics, 'analyze');
    jest.useFakeTimers();
    act(() => {
      render(<App />, container);
    });
    const button = document.querySelector('button');
    act(() => {
      button?.dispatchEvent(new MouseEvent('click', { bubbles: true }));
      jest.advanceTimersByTime(2000);
    });
    expect(analyzeSpy).toBeCalledTimes(1);
  });
});

測試結果:

PASS  examples/68400320/App.test.jsx (8.12 s)
  68400320
    ✓ should pass (52 ms)

  console.log
    Login

      at handleClick (examples/68400320/App.jsx:13:13)

  console.log
    TIMEOUT OVER

      at examples/68400320/App.jsx:6:13

  console.log
    Login success

      at onSuccess (examples/68400320/App.jsx:19:13)

  console.log
    Analysis done

      at Object.analyze (examples/68400320/Analytics.js:3:13)

--------------|---------|----------|---------|---------|-------------------
File          | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
--------------|---------|----------|---------|---------|-------------------
All files     |     100 |      100 |     100 |     100 |                   
 Analytics.js |     100 |      100 |     100 |     100 |                   
 App.jsx      |     100 |      100 |     100 |     100 |                   
--------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        8.666 s, estimated 10 s
Ran all test suites related to changed files.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM