简体   繁体   English

使用 Typescript 进行反应测试

[英]React Testing with Typescript

I'm having a few issues with testing in React with Typescript. I'm following a tutorial in React.js and am new to Typescript also so am not sure how to remove some errors.我在使用 Typescript 在 React 中进行测试时遇到了一些问题。我正在学习 React.js 中的教程并且是 Typescript 的新手,所以我不确定如何删除一些错误。

App.ts应用程序.ts

import { useState } from "react";
import validator from "validator";

interface signupInput {
    email: string;
    password: string;
    confirmPassword: string;
}

function App() {
    const [signupInput, setSignupInput] = useState<signupInput>({
        email: "",
        password: "",
        confirmPassword: "",
    });

    const [error, setError] = useState<string>("");

    const handleChange = (e: any) => {
        setSignupInput({
            ...signupInput,
            [e.target.name]: e.target.value,
        });
    };

    const handleClick = (e: any) => {
        e.preventDefault();
        if (!validator.isEmail(signupInput.email)) {
            return setError("the email you input is invalid");
        } else if (signupInput.password.length < 5) {
            return setError("your password needs 5 or more characters");
        } else if (signupInput.password !== signupInput.confirmPassword) {
            return setError("your passwords do not match");
        } else {
            return setError("");
        }
    };

    return (
        <div className="container my-5">
            <form>
                <div className="mb-3">
                    <label htmlFor="email" className="form-label">
                        Email Address
                    </label>
                    <input
                        type="email"
                        id="email"
                        name="email"
                        className="form-control"
                        value={signupInput.email}
                        onChange={handleChange}
                    />
                </div>
                <div className="mb-3">
                    <label htmlFor="password" className="form-label">
                        Password
                    </label>
                    <input
                        type="password"
                        id="password"
                        name="password"
                        className="form-control"
                        value={signupInput.password}
                        onChange={handleChange}
                    />
                </div>
                <div className="mb-3">
                    <label htmlFor="confirm-password" className="form-label">
                        Confirm Password
                    </label>
                    <input
                        type="password"
                        id="confirm-password"
                        name="confirmPassword"
                        className="form-control"
                        value={signupInput.confirmPassword}
                        onChange={handleChange}
                    />
                </div>
                {error && <p className="text-danger">{error}</p>}
                <button type="submit" className="btn btn-primary" onClick={handleClick}>
                    Submit
                </button>
            </form>
        </div>
    );
}

export default App;

I feel like I need to pass my interface signup through to the testing file which I've done and it has removed a lot of red lines but not sure if I've done it correctly.我觉得我需要将我的界面注册传递到我已经完成的测试文件,它已经删除了很多红线但不确定我是否正确完成了。

App.test.tsx应用程序测试.tsx

import { render, screen } from "@testing-library/react";
import App from "./App";
import "@testing-library/jest-dom/extend-expect";
import userEvent from "@testing-library/user-event";

interface signupInput {
    email: string;
    password: string;
    confirmPassword: string;
}

beforeEach(() => {
    // eslint-disable-next-line testing-library/no-render-in-setup
    render(<App />);
});

const typeIntoForm = ({ email, password, confirmPassword }: signupInput) => {
    const emailInputElement = screen.getByRole<HTMLInputElement>("textbox", {
        name: /email/i,
    });
    const passwordInputElement =
        screen.getByLabelText<HTMLInputElement>("Password");
    const confirmPasswordInputElement =
        screen.getByLabelText<HTMLInputElement>(/confirm password/i);
    if (email) {
        userEvent.type(emailInputElement, email);
    }
    if (password) {
        userEvent.type(passwordInputElement, password);
    }
    if (confirmPassword) {
        userEvent.type(confirmPasswordInputElement, confirmPassword);
    }
    return {
        emailInputElement,
        passwordInputElement,
        confirmPasswordInputElement,
    };
};

I'm trying to clean up my code.我正在尝试清理我的代码。 I'm not sure if I've passed the interface through correctly and also in my test:我不确定我是否已正确通过接口以及是否在我的测试中:

test("should be able to type an email", () => {
    const { emailInputElement } = typeIntoForm({
        email: "selena@gmail.com",
        password: "",
        confirmPassword: "",
    });
    expect(emailInputElement.value).toBe("selena@gmail.com");
});

if I remove:如果我删除:

password: "",
            confirmPassword: "",

from const { emailInputElement } I get an error:从 const { emailInputElement } 我得到一个错误:

Argument of type '{ email: string; }' is not assignable to parameter of type 'signupInput'.
  Type '{ email: string; }' is missing the following properties from type 'signupInput': password, confirmPasswordts(2345)

What could I change so I can only mention the email that isn't an empty string?我可以更改什么,所以我只能提及不是空字符串的 email?

Also if there is any good documentation for testing in Typescript.另外,如果 Typescript 中有任何好的测试文档。

You could try to modify the type of your typeIntoForm function like so:您可以尝试修改 typeIntoForm function 的类型,如下所示:

interface SignupInput {
    email?: string;
    password?: string;
    confirmPassword?: string;
}

const typeIntoForm = (input: SignupInput) => {

Or:或者:

const typeIntoForm = (Partial<SignupInput>: signupInput) => {

https://www.typescriptlang.org/docs/handbook/utility-types.html https://www.typescriptlang.org/docs/handbook/utility-types.html

https://www.typescriptlang.org/docs/handbook/2/functions.html#optional-parameters https://www.typescriptlang.org/docs/handbook/2/functions.html#optional-parameters

I suggest you capitalize your types and interfaces.我建议你利用你的类型和接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM