代码之家  ›  专栏  ›  技术社区  ›  Kevin.a

测试去抖动函数React-React测试库

  •  0
  • Kevin.a  · 技术社区  · 5 年前

    我有以下组件

    import React, { useState, useEffect } from 'react';
    import { FiSearch } from 'react-icons/fi';
    import { useProducts } from '../../hooks';
    
    export default function SearchBar() {
      const [query, setQuery] = useState('');
      const [debounced, setDebounced] = useState('');
    
      useEffect(() => {
        const timeout = setTimeout(() => {
          setDebounced(query);
        }, 300);
        return () => {
          clearTimeout(timeout);
        };
      }, [query]);
    
      const handleChange = (e) => {
        e.preventDefault();
        setQuery(e.target.value);
      };
    
      useProducts(debounced);
    
      return (
        <div className="search-form">
          <FiSearch className="search-form__icon" />
          <input
            type="text"
            className="search-form__input"
            placeholder="Search for brands or shoes..."
            onChange={handleChange}
            value={query}
          />
        </div>
      );
    }
    

    我想测试一下 useProducts(debounced); 实际上是在输入300毫秒后调用的。遗憾的是,我不知道从哪里开始,希望有人能帮助我。

    0 回复  |  直到 5 年前
        1
  •  3
  •   juliomalves    5 年前

    @testing-library/user-event 模拟用户在 <input> 要素第二,你会想嘲笑我 useProducts 实现来声明它在测试中被正确调用。

    import React from 'react';
    import { render, screen, waitFor } from '@testing-library/react';
    import userEvent from '@testing-library/user-event';
    import SearchBar from '<path-to-search-bar-component>'; // Update this accordingly
    import * as hooks from '<path-to-hooks-file>'; // Update this accordingly
    
    describe('Test <SearchBar />', () => {
        it('should call useProducts after 300ms after typing', async () => {
            const mockHook = jest.fn();
            jest.spyOn(hooks, 'useProducts').mockImplementation(mockHook);
            render(<SearchBar />);
            const input = screen.getByPlaceholderText('Search for brands or shoes...');
            userEvent.type(input, 'A');
            expect(mockHook).not.toHaveBeenCalledWith('A'); // It won't be called immediately
            await waitFor(() => expect(mockHook).toHaveBeenCalledWith('A'), { timeout: 350 }); // But will get called within 350ms
            jest.clearAllMocks();
        });
    });
    
    推荐文章