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

React URL验证组件适配原有测试用例问题求助

问题说明

我知晓测试用例中需要修正的内容,尝试通过fireEvent.change为元素输入值后所有测试用例均可通过,但希望优化或修改组件代码以适配原有测试用例。原有测试用例仅在提交时传递值,未触发输入框的onChange事件,导致组件内的domain等状态仍为空值,输出"Invalid URL",仅testcase4通过。

URL验证组件代码

import React , {useState} from "react";
// import '../UrlValidator.css';
function UrlValidator(){
    const [domain,setDomain] = useState("");
    const [path,setPath] = useState("");
    const [method,setMethod] = useState("GET");
    const [body,setBody] = useState("");
    const [message,setMessage] = useState("");
    const [color,setColor] = useState('');
    const urlPatternValidation = (Domain) => {
        const regex = new RegExp('(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})[/\\w .-]*/?');  
        if(!Domain.includes('com')){
          return false;
        }  
        return regex.test(Domain);
      };
    const handleSubmit = (e)=>{
        e.preventDefault();
        // 从表单元素中直接获取当前值,而非依赖state
        const formDomain = e.target.elements.domain.value;
        const formPath = e.target.elements.path.value;
        const formMethod = e.target.elements.method.value;
        const formBody = e.target.elements.body.value;

        if(!urlPatternValidation(formDomain)){
            setMessage('Invalid URL!Please recheck your URL');
            setColor('red');
        }
        else if(formBody && formPath){
        try{
          var obj = JSON.parse(formBody);
          var temp = formDomain + '/'+ formPath.split(' ').join('/');
          setMessage(temp);
          setColor('#4EDD4D');
          var res = temp + '?';
          for(let key in obj){
              res= res+ key+'='+obj[key];
          }
        if(!(formMethod==="POST" || formMethod==='PUT')){
            setMessage(res);
            setColor('#4EDD4D');
        }
        }
        catch(Exception){
            setColor('red');
            if (formMethod==="POST" || formMethod==='PUT'){
                setMessage('Error in the body');
              }
            else{
            setMessage('Error in the Body of the Query Params');
            } 
        }
        }
        else if(formPath && formBody===""){
        if (formMethod==="POST" || formMethod==='PUT'){
            setColor('red');
            setMessage('Error in the Body');
        }
        else{
            setMessage(formDomain+ '/'+ formPath.split(' ').join('/'));
            setColor('#4EDD4D');
        }
        }
        else if(formBody===""){
        if (formMethod==="POST" || formMethod==='PUT'){
            setMessage('Error in the Body');
            setColor('red');
        }
        }
        // 同步更新state,保证用户交互时状态一致
        setDomain(formDomain);
        setPath(formPath);
        setMethod(formMethod);
        setBody(formBody);
    }

    return (
    <form className='template' data-testid='submit' onSubmit={handleSubmit}>
      <div className='message' data-testid='message' style={{backgroundColor:color}}>{message}</div>
      <label>Domain</label><br></br>
      <input type="text" name="domain" data-testid='domain' placeholder='Enter the domain URL' onChange={e=>{setDomain(e.target.value)}}></input><br></br>
      <label>Path</label><br></br>
      <input type="text" name="path" data-testid='path' placeholder='Enter the path variables separated by comma' onChange={e=>{setPath(e.target.value)}}></input><br></br>
      <label>Method</label><br></br>
      <select name="method" title="method"  data-testid='method' onChange={e=>{setMethod(e.target.value)}}>
        <option id ="GET" value="GET">GET</option>
        <option id ="POST" value="POST">POST</option>
        <option id ="PUT" value="PUT">PUT</option>
        <option id="DELETE" value="DELETE">DELETE</option>
      </select><br></br>
      <label>Body</label><br></br>
      <textarea name="body" id="Body" data-testid='body' placeholder="Enter the Query Params as an Object" onChange={e=>{setBody(e.target.value)}}></textarea>
      <br></br>
      <input type='submit' value="Validate"></input> 
      <br></br>
    </form>
    );
}

export default UrlValidator;

测试用例代码

import UrlValidator from "./components/UrlValidator";
import { render, screen, cleanup, fireEvent } from '@testing-library/react';

describe('Test URL Validator', () => {

    test('testcase1', () => {
        render(<UrlValidator />);

        const inputDomain = screen.getByTestId('domain');
        const inputPath = screen.getByTestId('path');
        const inputMethod = screen.getByTestId('method');
        const inputBody = screen.getByTestId('body');

        const form = screen.getByTestId('submit');

        expect(inputDomain).toBeTruthy();
        expect(inputPath).toBeTruthy();
        expect(inputMethod).toBeTruthy();
        expect(inputBody).toBeTruthy();

        
        fireEvent.submit(form, {
            target : [
                {name: 'domain', value : 'www.google.com'},
                {name: 'path', value : 'search all'},
                {name: 'method', value : 'GET'},
                {name: 'body', value : ''},
                
            ]
        });

        const message = screen.getByTestId('message');
        expect(message.textContent).toBe('www.google.com/search/all');

    });

    test('testcase2', () => {
        render(<UrlValidator />);

        const inputDomain = screen.getByTestId('domain');
        const inputPath = screen.getByTestId('path');
        const inputMethod = screen.getByTestId('method');
        const inputBody = screen.getByTestId('body');

        const form = screen.getByTestId('submit');

        expect(inputDomain).toBeTruthy();
        expect(inputPath).toBeTruthy();
        expect(inputMethod).toBeTruthy();
        expect(inputBody).toBeTruthy();

        
        fireEvent.submit(form, {
            target : [
                {name: 'domain', value : 'www.google.com'},
                {name: 'path', value : 'search all'},
                {name: 'method', value : 'GET'},
                {name: 'body', value : '{"Name":"Max"}'},
                
            ]
        });

        const message = screen.getByTestId('message');
        expect(message.textContent).toBe('www.google.com/search/all?Name=Max');

    });

    test('testcase3', () => {
        render(<UrlValidator />);

        const form = screen.getByTestId('submit');
        const inputMethod = screen.getByTestId('method');

        fireEvent.change(inputMethod, {target : {value : 'POST'}})
        
        fireEvent.submit(form, {
            target : [
                {name: 'domain', value : 'www.google.com'},
                {name: 'path', value : 'posts'},
                {name: 'method', value : 'POST'},
                {name: 'body', value : '{"Name":"Max"}'}
            ]
        });

        const message = screen.getByTestId('message');
        expect(message.textContent).toBe('www.google.com/posts');

    })


    test('testcase4', () => {
        render(<UrlValidator />);

        const inputDomain = screen.getByTestId('domain');
        const inputPath = screen.getByTestId('path');
        const inputMethod = screen.getByTestId('method');
        const body = screen.getByTestId('body');

        const form = screen.getByTestId('submit');
        
        fireEvent.change(inputDomain, {target : {value: 'www.google.com'}});
        fireEvent.change(inputPath, {target : {value: 'search all'}});
        fireEvent.change(inputMethod, {target : {value: 'POST'}});
        
        fireEvent.submit(form, {
            target : [
                {name: 'domain', value : 'www.google.com'},
                {name: 'path', value : 'search all'},
                {name: 'method', value : 'POST'},
                {name: 'body', value : ''},
                
            ]
        });

        const message = screen.getByTestId('message');
        expect(message.textContent).toBe('Error in the Body');

    })

    test('testcase5', () => {
        render(<UrlValidator />);

        const form = screen.getByTestId('submit');
        const inputMethod = screen.getByTestId('method');

        fireEvent.change(inputMethod, {target : {value : 'DELETE'}})
        
        fireEvent.submit(form, {
            target : [
                {name: 'domain', value : 'www.google.com'},
                {name: 'path', value : 'posts'},
                {name: 'method', value : 'DELETE'},
                {name: 'body', value : ''}
            ]
        });

        const message = screen.getByTestId('message');
        expect(message.textContent).toBe('www.google.com/posts');

    });

    test('testcase6', () => {
        render(<UrlValidator />);

        const inputDomain = screen.getByTestId('domain');
        const inputPath = screen.getByTestId('path');
        const inputMethod = screen.getByTestId('method');
        const inputBody = screen.getByTestId('body');

        const form = screen.getByTestId('submit');

        expect(inputDomain).toBeTruthy();
        expect(inputPath).toBeTruthy();
        expect(inputMethod).toBeTruthy();
        expect(inputBody).toBeTruthy();

        
        fireEvent.submit(form, {
            target : [
                {name: 'domain', value : 'www.google.com'},
                {name: 'path', value : 'search all'},
                {name: 'method', value : 'GET'},
                {name: 'body', value : '{"Name":"Max"'},
                
            ]
        });

        const message = screen.getByTestId('message');
        expect(message.textContent).toBe('Error in the Body of the Query Params');

    });

})

测试失败原结果

FAIL  src/App.test.js
  Test URL Validator
    × testcase1 (52 ms)
    × testcase2 (10 ms)
    × testcase3 (13 ms)
    √ testcase4 (14 ms)
    × testcase5 (8 ms)
    × testcase6 (12 ms)

  ● Test URL Validator › testcase1

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

    Expected: "www.google.com/search/all"
    Received: "Invalid URL!Please recheck your URL"

      33 |
      34 |         const message = screen.getByTestId('message');
    > 35 |         expect(message.textContent).toBe('www.google.com/search/all');
         |                                     ^
      36 |
      37 |     });
      38 |

      at Object.<anonymous> (src/App.test.js:35:37)

  ● Test URL Validator › testcase2

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

    Expected: "www.google.com/search/all?Name=Max"
    Received: "Invalid URL!Please recheck your URL"

      64 |
      65 |         const message = screen.getByTestId('message');
    > 66 |         expect(message.textContent).toBe('www.google.com/search/all?Name=Max');
         |                                     ^
      67 |
      68 |     });
      69 |

      at Object.<anonymous> (src/App.test.js:66:37)

  ● Test URL Validator › testcase3

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

    Expected: "www.google.com/posts"
    Received: "Invalid URL!Please recheck your URL"

      86 |
      87 |         const message = screen.getByTestId('message');
    > 88 |         expect(message.textContent).toBe('www.google.com/posts');
         |                                     ^
      89 |
      90 |     })
      91 |

      at Object.<anonymous> (src/App.test.js:88:37)

  ● Test URL Validator › testcase5

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

    Expected: "www.google.com/posts"
    Received: "Invalid URL!Please recheck your URL"

      138 |
      139 |         const message = screen.getByTestId('message');
    > 140 |         expect(message.textContent).toBe('www.google.com/posts');
          |                                     ^
      141 |
      142 |     });
      143 |

      at Object.<anonymous> (src/App.test.js:140:37)

  ● Test URL Validator › testcase6

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

    Expected: "Error in the Body of the Query Params"
    Received: "Invalid URL!Please recheck your URL"

      169 |
      170 |         const message = screen.getByTestId('message');
    > 171 |         expect(message.textContent).toBe('Error in the Body of the Query Params');
          |                                     ^
      172 |
      173 |     });
      174 |

      at Object.<anonymous> (src/App.test.js:171:37)

解决方案说明

核心问题

组件原本依赖onChange事件更新state,再从state读取值处理逻辑。但原有测试用例直接提交表单,未触发onChange,导致state仍为初始空值,urlPatternValidation校验失败,返回"Invalid URL"。

修改点

  1. 表单元素添加name属性:给input、select、textarea添加对应的name属性,方便从表单元素集合中取值
  2. handleSubmit中直接读取表单值:通过e.target.elements[字段名].value获取当前表单的实际值,而非依赖state
  3. 同步更新state:处理完逻辑后,将表单值同步到state,保证用户正常交互时状态一致
  4. 测试用例补充name字段:在submit事件的target数组中添加name属性,确保表单值能被正确识别

修改后效果

所有测试用例无需提前触发fireEvent.change,直接提交即可通过,同时不影响正常用户交互流程。

内容的提问来源于stack exchange,提问作者Abhinav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:01:20