You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React登录测试遇TypeError:options.agent属性类型不符求助

登录功能测试报错排查:TypeError: The "options.agent" property must be one of Agent-like Object, undefined, or false

错误信息

TypeError: The "options.agent" property must be one of Agent-like Object, undefined, or false. Received an instance of Object

测试代码

import { QueryClient, QueryClientProvider } from 'react-query';
import SignIn from '../SignIn';
import { setupServer } from 'msw/node'
import { render, screen, fireEvent, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
import { rest } from 'msw';

// 配置server模拟登录API请求
let server = setupServer();
beforeAll(() => server.listen())
// afterEach(() => server.resetHandlers())
afterAll(() => server.close())

const queryClient = new QueryClient();
const onSubmit = jest.fn();

beforeEach(() => {
    //onSubmit.mockClear();
    render(
        <QueryClientProvider client={queryClient}>
            <SignIn onSuccess={onSubmit} />
        </QueryClientProvider>
    );
})

describe('SignIn Domain', () => {
    test('Successful login', async () => {

        server.use(
            rest.post('/api/Auth/Login', (req, res, ctx) => {
                return res(ctx.json([{ token: 'myToken' }]));
            }),
        );

        // 注意:这里getEmail()未定义,需替换为screen.getByLabelText('邮箱')之类的查询方法
        await waitFor(() => {
            fireEvent.change(screen.getByLabelText('邮箱'), {
                target: {
                    value: "myemail@gmail.com"
                }
            })
        });

        // 点击按钮
        await waitFor(() => {
            fireEvent.click(screen.getByText('Continue'));
        });
           
        await waitForElementToBeRemoved(screen.getByText('Processing...'));
    })
})

预期测试流程

  • 输入邮箱
  • 点击“Continue”(按钮变灰,加载时显示Spinner)
  • 页面渲染密码输入框
  • 输入密码
  • 点击“Sign In”

项目依赖配置(package.json)

{
  "name": "airdrop-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@fluentui/react": "^8.104.5",
    "@fluentui/react-icons": "^1.1.145",
    "@fluentui/react-icons-mdl2": "^1.3.29",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "@types/d3": "^6.7.5",
    "@types/file-saver": "^2.0.5",
    "@types/filesaver": "^0.0.30",
    "@types/geojson": "^7946.0.10",
    "@types/mapbox-gl": "^2.7.10",
    "@types/node": "^12.20.55",
    "@types/react": "^17.0.52",
    "@types/react-dom": "^17.0.18",
    "@types/react-motion": "0.0.29",
    "@types/react-router-dom": "^5.3.3",
    "axios": "^0.21.4",
    "d3": "^6.7.0",
    "d3-hexbin": "^0.2.2",
    "d3-svg-legend": "^2.25.6",
    "enzyme": "^3.11.0",
    "file-saver": "^2.0.5",
    "fluent": "^0.13.0",
    "formik": "^2.2.9",
    "mapbox-gl": "^2.12.0",
    "msw": "^0.28.2",
    "react": "^17.0.2",
    "react-cookie": "^4.1.1",
    "react-dom": "^17.0.2",
    "react-map-gl": "^6.1.21",
    "react-motion": "^0.5.2",
    "react-query": "^3.39.2",
    "react-rnd": "^10.4.1",
    "react-router-dom": "^5.3.4",
    "react-scripts": "5.0.1",
    "sprintf-js": "^1.1.2",
    "typescript": "^4.9.4",
    "web-vitals": "^1.1.2",
    "yup": "^0.32.11"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@types/d3-hexbin": "^0.2.3",
    "@types/enzyme": "^3.10.12",
    "@types/enzyme-adapter-react-16": "^1.0.6",
    "@types/sprintf-js": "^1.1.2",
    "enzyme-adapter-react-15": "^1.4.4",
    "enzyme-adapter-react-16": "^1.15.7",
    "jest": "^29.3.1",
    "jest-environment-jsdom": "^29.3.1",
    "ts-jest": "^29.0.3",
    "whatwg-fetch": "^3.6.2"
  }
}

问题排查与解决方案

核心原因

这个错误是因为msw@0.28.2(旧版本)与jest@29.x的HTTP Agent不兼容,旧版msw在处理请求时传递的agent格式不符合Node.js最新版本的要求。另外测试代码本身也存在一些语法和逻辑问题。

分步解决

  1. 更新msw到兼容版本
    旧版msw(0.28.x)不支持jest29,建议升级到0.35.x及以上版本:

    npm install msw@^0.35.0 --save-dev
    

    升级后无需大幅修改测试代码,0.35.x仍支持setupServer的旧用法。

  2. 修复测试代码中的语法/逻辑问题

    • 取消注释afterEach(() => server.resetHandlers()),避免不同测试用例的请求处理逻辑互相污染。
    • 替换未定义的getEmail(),改用screen提供的查询方法,比如screen.getByLabelText('邮箱')(根据SignIn组件的实际label调整)。
    • 修正测试函数的闭合括号:把)}改成})(共两处)。
  3. 可选:调整axios配置(若更新msw后仍报错)
    如果SignIn组件使用axios发送请求,可在axios实例中显式禁用agent:

    import axios from 'axios';
    
    const apiClient = axios.create({
      // 其他配置
      httpAgent: false,
      httpsAgent: false,
    });
    

修正后的测试代码片段

// 恢复afterEach重置handler
afterEach(() => server.resetHandlers())

// ...

test('Successful login', async () => {
    server.use(
        rest.post('/api/Auth/Login', (req, res, ctx) => {
            return res(ctx.json([{ token: 'myToken' }]));
        }),
    );

    // 替换为实际的邮箱输入框查询方式
    const emailInput = screen.getByLabelText('邮箱');
    fireEvent.change(emailInput, { target: { value: "myemail@gmail.com" } });

    fireEvent.click(screen.getByText('Continue'));
       
    await waitForElementToBeRemoved(screen.getByText('Processing...'));
    // 后续可添加密码输入和SignIn点击的测试逻辑
})

内容的提问来源于stack exchange,提问作者T-O

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 01:00:48