使用 Jest 测试登录组件

ss_*_*hes 5 javascript reactjs jestjs enzyme

我不擅长测试,而且对 Jest 和 Enzyme 还很陌生。我有一个登录组件,由两个用于用户名和密码的 TextInput 组件和一个按钮组件组成。我正在单独测试每个组件。

我只是想测试 onLogin 是否返回了用户名和密码。

这是该组件:

export const onLogin = (user, password) => {
  console.log('User', user, 'Password', password)
  return [user, password];
};

function Login() {
  const [user, setUser] = useState("");
  const [password, setPassword] = useState("");

  return (
    <LoginWrapper>
      <Branding brand={brand.brandName} />
      <FormWrapper onSubmit={(e) => { e.preventDefault(); onLogin(user, password) }}>
        <Stack>
          <TextInput
            className="username"
            type="text"
            label="Username"
            onChange={e => setUser(e.target.value)}
          />
        </Stack>
        <Stack>
          <TextInput
            className="password"
            type="password"
            label="Password"
            onChange={e => {setPassword(e.target.value); console.log('user', user)}}
          />
        </Stack>
        <Stack padding="0" align="right">
          <Button type="submit">Login</Button>
        </Stack>
      </FormWrapper>
    </LoginWrapper>
  );
}

export default Login;
Run Code Online (Sandbox Code Playgroud)

我的测试:

describe("<Login />", () => {
  it("renders text input correctly", () => {
    const tree = renderer.create(<ThemeProvider theme={themes.default}><Login /></ThemeProvider>).toJSON();
    expect(tree).toMatchSnapshot();
  });

  it("calls onLogin when button clicked", () => {
    const onSubmitMock = jest.fn();

    const component = Enzyme.mount(
      <ThemeProvider theme={themes.default}><Login onSubmit={onSubmitMock} /></ThemeProvider>
    );

    component.find("input.username").simulate('change', { target: { value: 'myUser' } })
    component.find("input.password").simulate('change', { target: { value: 'myPassword' } })
    component.find("form").simulate("submit");

    console.log("onClickMock.mock", onSubmitMock.mock)
    expect(onSubmitMock).toBeCalled()
  });
});
Run Code Online (Sandbox Code Playgroud)

结果:

预期已调用模拟函数,但实际未调用。

Jua*_*vas 3

您的测试方法是正确的,除了:

  1. 在您的测试中,您正在模拟回调函数并将其作为属性传递onSubmit给您的组件。然后,您需要在提交表单时从组件中调用此函数。
  2. 相反,您onLogin在组件上调用不会产生任何影响的函数。

为了解决这个问题,请将组件函数的属性声明为参数,然后调用props.onSubmit表单提交。

function Login(props) {
    const [user, setUser] = useState("");
    const [password, setPassword] = useState("");

    return (
        <LoginWrapper>
            <Branding brand={brand.brandName} />
            <FormWrapper onSubmit={(e) => { e.preventDefault(); props.onSubmit(user, password) }}>
                <Stack>
                    <TextInput
                        className="username"
                        type="text"
                        label="Username"
                        onChange={(e) => setUser(e.target.value)}
                    />
                </Stack>
                <Stack>
                    <TextInput
                        className="password"
                        type="password"
                        label="Password"
                        onChange={(e) => { setPassword(e.target.value) }}
                    />
                </Stack>
                <Stack padding="0" align="right">
                    <Button type="submit">Login</Button>
                </Stack>
            </FormWrapper>
        </LoginWrapper>
    );
}

Run Code Online (Sandbox Code Playgroud)