简体   繁体   English

用 jest 和酵素测试 React 组件

[英]Tests React component with jest and enzyme

i have components presented below.我有下面介绍的组件。 I am totally new in unit testing.我是单元测试的新手。 Can anyone give any one give me advice how and what should I test in this component?任何人都可以给任何人建议我应该如何以及在这个组件中测试什么? I was trying to shallow render it, to check is text in h2 is present but i still getting errors.我试图对其进行浅层渲染,以检查 h2 中的文本是否存在,但我仍然遇到错误。

import React, { useEffect } from 'react';
import { Form, Field } from 'react-final-form';
import { useHistory, Link } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { loginUser, clearErrorMessage } from '../../redux/auth/authActions';
import Input from '../Input/Input';
import ROUTES from '../../routes/routes';
import './LoginForm.scss';

const LoginForm = () => {
  const dispatch = useDispatch();
  const history = useHistory();

  const { loading, isLogged, errorMessage } = useSelector(state => state.auth);

  useEffect(() => {
    if (isLogged) {
      history.push('/');
    }

    return () => {
      dispatch(clearErrorMessage());
    };
  }, [dispatch, history, isLogged]);

  const handleSubmitLoginForm = values => {
    if (!loading) {
      dispatch(loginUser(values));
    }
  };

  const validate = ({ password }) => {
    const errors = {};

    if (!password) {
      errors.password = 'Enter password!';
    }

    return errors;
  };

  return (
    <article className="login-form-wrapper">
      <h2>SIGN IN</h2>
      <Form onSubmit={handleSubmitLoginForm} validate={validate}>
        {({ handleSubmit }) => (
          <form onSubmit={handleSubmit} autoComplete="off" className="login-form">
            <div className="login-form__field">
              <Field name="email" component={Input} type="email" label="E-mail" />
            </div>
            <div className="login-form__buttons">
              <button type="submit" className={loading ? 'button-disabled' : ''}>
                Sign in
              </button>
            </div>
          </form>
        )}
      </Form>
    </article>
  );
};

export default LoginForm;

I am open for any advices:)我愿意接受任何建议:)

First of all, I am not recommending using shallow in your tests and here is a great article why.首先,我不建议在你的测试中使用shallow是一篇很棒的文章为什么。

I also recommend to check out react-testing-library instead of Enzyme as it is much nicer to use.我还建议查看react-testing-library而不是 Enzyme,因为它更好用。

Now, to answer your question.现在,回答你的问题。 You are using here hooks for redux and react-router , so you need to provide the necessary data to your componenent in test so that it can use those hooks.您在此处使用reduxreact-router的钩子,因此您需要在测试中为您的组件提供必要的数据,以便它可以使用这些钩子。 Let me show you an example test (that checks text in h2 element):让我向您展示一个示例测试(检查h2元素中的文本):

import React from 'react';
import { mount } from 'enzyme';
import {Provider} from 'react-redux';
import {MemoryRouter, Route} from 'react-router';
import LoginForm from './LoginForm';

describe('Login Form', () => {
  it('should have SIGN IN header', () => {
    const store = createStore();
    const component = mount(
      <Provider store={store}>
        <MemoryRouter initialEntries={['/login']}>
          <Route path="/:botId" component={LoginForm} />
        </MemoryRouter>
      </Provider>
    )

    expect(component.find('h2').text()).toEqual('SIGN IN');
  });
});

Some explanation to this example.对这个例子的一些解释。

  • I am using mount instead of shallow as I prefer to render as much as possible in my test, so that I can check if everything works together as it should.我使用mount而不是shallow ,因为我更喜欢在我的测试中尽可能多地渲染,这样我就可以检查一切是否正常工作。
  • You can see that I am not rendering my component directly, but rather it is wrapped with other components ( Provider from react-redux and MemoryRouter from react-router ).您可以看到我没有直接渲染我的组件,而是将它与其他组件包装在一起(来自react-reduxProvider和来自MemoryRouterreact-router )。 Why?为什么? Because I need to provide context to my Component.因为我需要为我的组件提供上下文 In this case it's redux and router context so that the data used inside exists and can be found (for example useSelector(state => state.auth) must have some state provided so that it can access auth property).在这种情况下,它是reduxrouter上下文,以便内部使用的数据存在并且可以找到(例如useSelector(state => state.auth)必须具有一些auth属性),以便它可以访问If you remove any of them you would get some error saying that this context is missing - go ahead and check for yourself:).如果您删除其中任何一个,您会收到一些错误消息,指出缺少此上下文 - go 提前并检查自己:)。
  • See here for some details around testing with router context有关使用router上下文进行测试的一些详细信息,请参见此处
  • As for testing with redux in my example there is a createStore function that I didn't define as there are a few approaches to this.至于在我的示例中使用redux进行测试,有一个我没有定义的createStore function,因为有几种方法可以解决这个问题。 One involves creating a real store that you use in your production application.其中之一涉及创建一个您在生产应用程序中使用的真实商店。 This is the one that I prefer and colleague of mine wrote great article around this topic here .这是我更喜欢的,我的同事在这里围绕这个主题写了一篇很棒的文章。 Other is to create some kind of mock store, like in this article .其他是创建某种模拟商店,就像在这篇文章中一样。 Again, I prefer the first approach, but whichever is better for you.同样,我更喜欢第一种方法,但无论哪种方式更适合您。

Answering your other question on what should you test in this example.回答您在此示例中应该测试什么的其他问题。 There are multiple possibilities.有多种可能性。 It all depends mostly on you business case, but examples that I would test here includes:这主要取决于您的业务案例,但我将在这里测试的示例包括:

  • Typing something into an input, clicking a button and observing that login is successful (by redirecting to new path - / in this case)在输入中输入内容,单击按钮并观察登录是否成功(通过重定向到新路径 - 在这种情况下是/
  • not typing a password and clicking a button - error should be shown未输入密码并单击按钮 - 应显示错误
  • Checking if button class changes when it's loading检查按钮 class 在加载时是否发生变化
  • Do not dispatch login action twice, when already loading不要在已经加载时分派登录操作两次

And so on...等等...

That's really just a tip of an iceberg on what could be written around testing, but I hope it helps and gives you a nice start to dig deeper into the topic.这实际上只是关于可以围绕测试编写的内容的冰山一角,但我希望它对您有所帮助,并为您提供深入研究该主题的良好开端。

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

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