1

我正在调整我的一些 React 代码以使用@testing-library/react,react-querymsw模拟我使用的网络调用axios

到目前为止(经过一些脑筋急转弯)我已经使用这段代码了!(耶!)

有问题的测试(简化):

import React from 'react';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
import { queryCache } from 'react-query';
import userEvent from '@testing-library/user-event';
import Login from '../Login';
import { render, queryClient } from '~/testhelpers/helpers.integration';
// #endregion imports

const server = setupServer(
    // ...default setup for successful request; not relevant here
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

describe('rendering', () => {
    describe('error', () => {
        it.only('should render error message when request fails', async () => {
            server.use(
                rest.post(`${API_BASE_URL}api/auth/token`, (req, res, ctx) => {
                    return res(ctx.status(400), ctx.json('Invalid username or password.'));
                })
            );
            render(<Login />);
            const usernameInput = screen.getByLabelText('Username');
            const passwordInput = screen.getByLabelText('Password');
            const submitInput = screen.getByRole('button', { name: 'Login' });
            userEvent.type(usernameInput, 'testUsername');
            userEvent.type(passwordInput, 'testPassword');
            userEvent.click(submitInput);
            await waitFor(() => {
                expect(screen.getByText('Invalid username or password.')).toBeInTheDocument();
            });
        });
    });
});

同样,这个测试有效!万岁!但问题是我正在axios考虑(通过msw)它正在接收此查询的 400 响应,并且当我使用 Jest 运行此测试时,我在控制台中收到了一大块错误消息:

 PASS  src/display/views/login/__tests__/Login.spec.js
  rendering
    error
      √ should hide loading indicator and render error message when request fails (522 ms)

  console.error
    Error: Request failed with status code 400
        at createError (C:\Users\me\Documents\_Programming\GitHub\my-project\node_modules\axios\lib\core\createError.js:16:15)
        at settle (C:\Users\me\Documents\_Programming\GitHub\my-project\node_modules\axios\lib\core\settle.js:18:12)
        at XMLHttpRequestOverride.handleLoad [as onreadystatechange] (C:\Users\me\Documents\_Programming\GitHub\my-project\node_modules\axios\lib\adapters\xhr.js:59:7)
        at XMLHttpRequestOverride.triggerReadyStateChange (C:\Users\me\Documents\_Programming\GitHub\my-project\node_modules\node-request-interceptor\src\interceptors\XMLHttpRequest\XMLHttpRequestOverride.ts:133:33)     
        at XMLHttpRequestOverride.trigger (C:\Users\me\Documents\_Programming\GitHub\my-project\node_modules\node-request-interceptor\src\interceptors\XMLHttpRequest\XMLHttpRequestOverride.ts:145:12)
        at C:\Users\me\Documents\_Programming\GitHub\my-project\node_modules\node-request-interceptor\src\interceptors\XMLHttpRequest\XMLHttpRequestOverride.ts:306:18
        at runNextTicks (internal/process/task_queues.js:62:5)
        at processTimers (internal/timers.js:489:9) {
      config: {
        adapter: [Function: xhrAdapter],
        transformRequest: { '0': [Function: transformRequest] },
        transformResponse: { '0': [Function: transformResponse] },
        timeout: 0,
        xsrfCookieName: 'XSRF-TOKEN',
        xsrfHeaderName: 'X-XSRF-TOKEN',
        maxContentLength: -1,
        validateStatus: [Function: validateStatus],
        headers: {
          Accept: 'application/json, text/plain, */*',
          'Content-Type': 'application/json;charset=utf-8'
        },
        method: 'post',
        url: 'http://baseurl/api/auth/token',
        data: '{"username":"testUsername","password":"testPassword"}'
      },
      request: XMLHttpRequestOverride {
        requestHeaders: {
          Accept: 'application/json, text/plain, */*',
          'Content-Type': 'application/json;charset=utf-8'
        },
        responseHeaders: { 'x-powered-by': 'msw', 'content-type': 'application/json' },
        _events: [],
        UNSENT: 0,
        OPENED: 1,
        HEADERS_RECEIVED: 2,
        LOADING: 3,
        DONE: 4,
        onreadystatechange: [Function: handleLoad],
        onabort: null,
        onerror: [Function: handleError],
        onload: null,
        onloadend: null,
        onloadstart: null,
        onprogress: null,
        ontimeout: [Function: handleTimeout],
        url: 'http://baseurl/api/auth/token',
        method: 'POST',
        readyState: 4,
        withCredentials: false,
        status: 400,
        statusText: 'Bad Request',
        data: '{"username":"testUsername","password":"testPassword"}',
        response: '"Invalid username or password."',
        responseType: 'text',
        responseText: '"Invalid username or password."',
        responseXML: null,
        responseURL: '',
        upload: null,
        timeout: 0,
        async: true,
        user: undefined,
        password: undefined
      },
      response: {
        data: 'Invalid username or password.',
        status: 400,
        statusText: 'Bad Request',
        headers: { 'x-powered-by': 'msw', 'content-type': 'application/json' },
        config: {
          adapter: [Function: xhrAdapter],
          transformRequest: [Object],
          transformResponse: [Object],
          timeout: 0,
          xsrfCookieName: 'XSRF-TOKEN',
          xsrfHeaderName: 'X-XSRF-TOKEN',
          maxContentLength: -1,
          validateStatus: [Function: validateStatus],
          headers: [Object],
          method: 'post',
          url: 'http://baseurl/api/auth/token',
          data: '{"username":"testUsername","password":"testPassword"}'
        },
        request: XMLHttpRequestOverride {
          requestHeaders: [Object],
          responseHeaders: [Object],
          _events: [],
          UNSENT: 0,
          OPENED: 1,
          HEADERS_RECEIVED: 2,
          LOADING: 3,
          DONE: 4,
          onreadystatechange: [Function: handleLoad],
          onabort: null,
          onerror: [Function: handleError],
          onload: null,
          onloadend: null,
          onloadstart: null,
          onprogress: null,
          ontimeout: [Function: handleTimeout],
          url: 'http://baseurl/api/auth/token',
          method: 'POST',
          readyState: 4,
          withCredentials: false,
          status: 400,
          statusText: 'Bad Request',
          data: '{"username":"testUsername","password":"testPassword"}',
          response: '"Invalid username or password."',
          responseType: 'text',
          responseText: '"Invalid username or password."',
          responseXML: null,
          responseURL: '',
          upload: null,
          timeout: 0,
          async: true,
          user: undefined,
          password: undefined
        }
      }
    }

      at CustomConsole.console.error (node_modules/@testing-library/react/dist/act-compat.js:52:34)
      at node_modules/react-query/lib/core/mutation.js:115:32

我认为,在某种程度上,这是意料之中的,但在我的测试中这真的是不必要的垃圾邮件,因为我期待并且实际上希望该请求失败。有没有一种最佳实践方法可以通过 Jest、RTL、msw 或 Axios 的配置来删除这个不必要的日志?

4

1 回答 1

0

默认情况下,react-query 将日志记录到控制台,您可以使用以下命令覆盖它setLogger

import { setLogger } from 'react-query'

setLogger({
  log: printLog,
  warn: printWarn,
  error: printError,
 })

另见:https ://react-query.tanstack.com/reference/setLogger

于 2021-02-28T06:24:33.170 回答