【问题标题】:Dealing with post requests and tokens while testing a React application with Jest在使用 Jest 测试 React 应用程序时处理发布请求和令牌
【发布时间】:2021-09-10 21:14:43
【问题描述】:

这是我第一次使用 jest 和 react。我创建了一个应用程序,要求用户通过身份验证才能访问某些资源。

我在登录组件中创建了以下功能,用于对服务器进行 axios 调用的身份验证-


    const loginUtil = async() => {

        const res = await axios
            .post("http://localhost:8080/user/authenticate", {
                username,
                password,
            });

        console.log(res.data);
        
        if (res.data.jwt) {
            localStorage.setItem("user", JSON.stringify(res.data));
        } else {
            throw new Error();
        }
        return JSON.stringify(res.data);
    }

    return loginUtil();
};

我为组件写了以下两个Jest测试用例-

import * as React from 'react'
import { rest } from 'msw'
import { setupServer } from 'msw/node'
import { render, fireEvent, screen } from '@testing-library/react'
import Login from '../Login'
import {jest} from '@jest/globals'

const fakeUserResponse = {jwt: 'fake_user_token',user : {
    username : 'jane',
    pasword : 'pass',
    role : 'user',
    id : 'ftrb3344grr'
}}
const server = setupServer(
  rest.post('http://localhost:8080/user/authenticate', (req, res, ctx) => {
    return res(ctx.json(fakeUserResponse))
  }),
);

beforeAll(() => server.listen())

beforeEach(() => {
    jest.spyOn(console, 'warn').mockImplementation(() => {});
  });

afterEach(() => {
    server.resetHandlers()
    window.localStorage.removeItem('user')
  })

afterAll(() => server.close())

test('token is saved correctly', async() => {
    
    render(<Login />)
  
    fireEvent.change(screen.getByPlaceholderText(/username/i), {
      target: {value: 'jane'},
    })

    fireEvent.change(screen.getByPlaceholderText(/password/i), {
      target: {value: 'pass'}
    })

    fireEvent.click(screen.getByTestId(/login/i))

    expect(localStorage.getItem('user')).toEqual(fakeUserResponse)
})

第一个测试用例通过但第二个没有。我也收到以下错误 -

Error message in the console

 FAIL  src/components/__tests__/Login.test.js (6.919 s)
  ● token is saved correctly

    expect(received).toEqual(expected) // deep equality

    Expected: {"jwt": "fake_user_token", "user": {"id": "ftrb3344grr", "pasword": "pass", "role": "user", "username": "jane"}}
    Received: null

      61 |     fireEvent.click(screen.getByTestId(/login/i))
      62 |
    > 63 |     expect(localStorage.getItem('user')).toEqual(fakeUserResponse)
         |                                          ^
      64 | })
      65 |

      at Object.<anonymous> (src/components/__tests__/Login.test.js:63:42)


  ●  Cannot log after tests are done. Did you forget to wait for something async in your test?
    Attempted to log "{
      jwt: 'fake_user_token',
      user: {
        username: 'jane',
        pasword: 'pass',
        role: 'user',
        id: 'ftrb3344grr'
      }
    }".

      16 |         } else {
      17 |             throw new Error();
    > 18 |         }
         |          ^
      19 |         return JSON.stringify(res.data);
      20 |     }
      21 |

      at BufferedConsole.log (node_modules/@jest/console/build/BufferedConsole.js:197:10)
      at loginUtil (src/service/authService.js:18:13)

这告诉我的是模拟服务器正确发送了响应数据,但由于某种原因,数据无法登录到控制台。测试不再给出预期结果。

任何关于为什么会发生这种情况的帮助将不胜感激。

提前谢谢你。

【问题讨论】:

    标签: javascript node.js reactjs unit-testing jestjs


    【解决方案1】:

    您可以模拟本地存储,供您使用。这是一个例子。

    //Storage Mock
    const storageMock = () => {
     let storage = {};
    
     return {
       setItem:(key, value) => {
        storage[key] = value || '';
       },
       getItem: (key) => {
        return storage[key] || null;
       },
       removeItem: (key) => {
        delete storage[key];
       },
       clear: function() {
        store = {};
       },
       getLength: () => {
        return Object.keys(storage).length;
       },
       key: function(i) {
        const keys = Object.keys(storage);
        return keys[i] || null;
       }
     };
    }
    

    然后你会做类似的事情:

    // mock the localStorage
    window.localStorage = storageMock();
    // mock the sessionStorage
    window.sessionStorage = storageMock();
    

    【讨论】:

    • 我尝试在我的测试脚本中使用它。但显然测试在返回结果之前完成了它的执行。
    猜你喜欢
    • 2017-09-14
    • 2018-12-31
    • 2010-11-09
    • 1970-01-01
    • 2016-09-14
    • 2019-12-21
    • 2020-12-19
    • 2015-09-13
    • 2019-05-29
    相关资源
    最近更新 更多