簡體   English   中英

使用 React 測試庫測試異步方法

[英]Testing async method using React testing library

我在組件中有按鈕:

<button
    type="button"
    title="Logout"
    data-testid="logout"
    onClick={logout}
>

和方法logout

const logout = async () => {
    try {
        await authLogout()
    } catch (error) {
        console.error(error)
    } finally {
        props.history.push('/login')
    }
}

現在我嘗試通過單擊按鈕測試注銷方法:

describe('UserMenuComponent', () => {
  it('go to login page after click on logout', async () => {
    const history = createMemoryHistory()

    const { getByTestId } = render(
      <Router history={history}>
        <UserMenuComponent />,
      </Router>,
      {
        initialState: { reducersAuth: initialState },
      },
    )

    fireEvent.click(getByTestId('logout'))
    expect(history.location.pathname).toBe('/login')
  })
})

finally塊中的方法logout內部我有props.history.push('/login')並且我在我的測試中檢查了這個: expect(history.location.pathname).toBe('/login')但測試返回錯誤:

expect(received).toBe(expected) // Object.is equality

Expected: "/login"
Received: "/"

您應該使用useHistory()掛鈎來獲取 SFC 中的歷史 object。

此外,由於logout function 是異步 function,您應該使用waitFor方法等待您的期望通過。

例如

UserMenuComponent.tsx

import React from 'react';
import { useHistory } from 'react-router-dom';

async function authLogout() {}

export function UserMenuComponent() {
  const history = useHistory();
  const logout = async () => {
    try {
      await authLogout();
    } catch (error) {
      console.error(error);
    } finally {
      history.push('/login');
    }
  };

  return <button type="button" title="Logout" data-testid="logout" onClick={logout}></button>;
}

UserMenuComponent.test.tsx

import { fireEvent, render, waitFor } from '@testing-library/react';
import React from 'react';
import { Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';
import { UserMenuComponent } from './UserMenuComponent';

describe('UserMenuComponent', () => {
  it('go to login page after click on logout', async () => {
    const history = createMemoryHistory();
    const pushSpy = jest.spyOn(history, 'push');

    const { getByTestId } = render(
      <Router history={history}>
        <UserMenuComponent />,
      </Router>
    );

    fireEvent.click(getByTestId('logout'));
    await waitFor(() => {
      expect(pushSpy).toBeCalledWith('/login');
      expect(history.location.pathname).toBe('/login');
    });
  });
});

測試結果:

 PASS  examples/66571376/UserMenuComponent.test.tsx
  UserMenuComponent
    ✓ go to login page after click on logout (82 ms)

-----------------------|---------|----------|---------|---------|-------------------
File                   | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------------------|---------|----------|---------|---------|-------------------
All files              |   91.67 |      100 |     100 |   90.91 |                   
 UserMenuComponent.tsx |   91.67 |      100 |     100 |   90.91 | 12                
-----------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.881 s, estimated 4 s

您可以使用waitFor等待您的期望通過。

await waitFor(() => expect(history.location.pathname).toBe('/login'))

暫無
暫無

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

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