【问题标题】:Unit test doesn't update value on styled input单元测试不会更新样式输入的值
【发布时间】:2020-05-16 03:02:09
【问题描述】:

我正在测试一个 React 组件

import React from 'react';

import styled from 'styled-components';

const Input = styled.input``;

export default function FormInput (props) {
  const { name, type, value, label, placeholder, onChange} = props;

  return (
      <Input
        id={name}
        name={name}
        type={type}
        placeholder={placeholder}
        onChange={onChange}
        value={value}
      />
  )
};

使用这个单元测试

test('it changes the value of the input', () => {
  let currentValue = 'Initial value';
  const setValue = (value) => {
    currentValue = value;
  }

  const component = <FormInput 
    name={'firstName'} 
    placeholder={'Enter your first name'} 
    value={currentValue} 
    onChange={(e) => setValue(e.target.value)} />

  render(component);

  const input = screen.getByPlaceholderText('Enter your first name');

  fireEvent.change(input, {target: {value: 'New value'}});

  expect(currentValue).toBe('New value');
  expect(input.value).toBe('New value');
});

对输入值的断言是假的,因为它仍然是初始值。该组件在应用程序中正常工作。我在测试中设置了哪些错误?

【问题讨论】:

    标签: reactjs jestjs react-testing-library


    【解决方案1】:

    我发现使用@testing-library/user-event 包可以很容易地模拟用户的文本输入。

    import userEvent from '@testing-library/user-event';
    
    test('it changes the value of the input', () => {
      let currentValue = 'Initial value';
      const setValue = (value) => {
        currentValue = value;
      }
    
      const component = <FormInput 
        name={'firstName'} 
        placeholder={'Enter your first name'} 
        value={currentValue} 
        onChange={(e) => setValue(e.target.value)} />
    
      render(component);
    
      const input = screen.getByPlaceholderText('Enter your first name');
    
      userEvent.type(input, 'New value');
    
      expect(currentValue).toBe('New value');
      expect(input.value).toBe('New value');
    });
    

    【讨论】:

      【解决方案2】:

      为什么不将 setValue 放在组件主体中?这个逻辑显然属于组件,你应该有:

      import React, { useState } from 'react';
      
      import styled from 'styled-components';
      
      const Input = styled.input``;
      
      export default function FormInput (props) {
        const { name, type, label, placeholder} = props;
        const [value, setValue] = useState('');
      
        return (
            <input
              id={name}
              name={name}
              type={type}
              placeholder={placeholder}
              value={value}
              onChange={(e) => setValue(e.target.value)}
            />
        )
      };
      

      然后在你的测试中:

      import '@testing-library/jest-dom/extend-expect';
      
      test('it changes the value of the input', () => {
          const component = <FormInput 
              name={'firstName'} 
              placeholder={'Enter your first name'} 
              value={currentValue} />
      
          render(component);
      
          const input = screen.getByPlaceholderText('Enter your first name');
      
          fireEvent.change(input, { target : { value : 'New value' } });
          expect(input).toHaveValue('New value');
      });
      

      请注意,我使用 https://github.com/testing-library/jest-dom 来获得更易读的匹配器。

      【讨论】:

        【解决方案3】:

        单元测试失败,因为它没有被重新渲染。我使用rerender 函数来呈现具有更新值的组件。这是必要的,因为此测试不包括父组件保持状态。

        更新测试

        test('it changes the value of the input', async () => {
          let currentValue = 'Initial value';
          const setValue = (value) => {
            currentValue = value;
          }
        
          const component = <FormInput 
            name={'firstName'} 
            placeholder={'Enter your first name'} 
            value={currentValue} 
            onChange={(e) => setValue(e.target.value)} />
        
          const { rerender } = render(component);
        
          const input = screen.getByPlaceholderText('Enter your first name');
        
          fireEvent.change(input, {target: {value: 'New value'}});
        
          rerender(<FormInput value={currentValue} />);
        
          expect(input.value).toBe('New value');
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-03-18
          • 2017-04-25
          • 2013-04-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-26
          相关资源
          最近更新 更多