【问题标题】:Testing async method using React testing library使用 React 测试库测试异步方法
【发布时间】:2021-06-08 18:53:45
【问题描述】:

我在组件中有按钮:

<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: "/"

【问题讨论】:

    标签: reactjs react-router jestjs react-testing-library


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您应该使用 useHistory() 挂钩来获取 SFC 中的历史对象。

      另外,由于logout函数是一个异步函数,你应该使用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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-13
        • 1970-01-01
        • 1970-01-01
        • 2020-07-14
        相关资源
        最近更新 更多