Skip to main content

测试

<<<<<<< HEAD

在 React 之外测试 Recoil Selectors#

=======

Testing Recoil state inside of a React component#

It can be helpful to test Recoil state when testing a component. You can compare the new state against expected values using this pattern. It uses a React functional component, useRecoilValue and useEffect, to observe an atom/selector's changes and execute a callback every time the user performs an action that modifies the state.

export const RecoilObserver = ({node, onChange} => {  const value = useRecoilValue(node);  useEffect(() => onChange(value), [onChange, value]);  return null;};
  • node: can be an atom or a selector.
  • onChange: this function will be called every time the state changes.

Example: Form state modified by user#

Component#

import {atom, useRecoilState} from 'recoil';
export const nameAtom = atom({  key: 'nameAtom',  default: '',});
function Form() {  const [name, setName] = useRecoilState(nameAtom);  return (    <form>      <input        data-testid="name_input"        type="text"        value={name}        onChange={(event) => setName(event.target.value)}      />    </form>  );}
export default Form;

Test#

import {RecoilRoot} from 'recoil';import {fireEvent, render, screen} from '@testing-library/react';
import Form, {nameAtom} from './form';import {RecoilObserver} from './RecoilObserver';
describe('The form state should', () => {  test('change when the user enters a name.', () => {    const onChange = jest.fn();
    render(      <RecoilRoot>        <RecoilObserver node={nameAtom} onChange={onChange} />        <Form />      </RecoilRoot>    );
    const component = screen.getByTestId('name_input');
    fireEvent.change(component, {target: {value: 'Recoil'}});
    expect(onChange).toHaveBeenCalledTimes(2);    expect(onChange).toHaveBeenCalledWith(''); // Initial state on render.    expect(onChange).toHaveBeenCalledWith('Recoil'); // New value on change.  });});

Testing Recoil state outside of React#

7bffcb92ce0164c6bb5676ec991d1b0e6a449331

在 React 上下文之外操作和评估 Recoil selectors 以进行测试是非常有用的。这可以通过使用 Recoil Snapshot 来实现。您可以使用 snapshot_UNSTABLE() 生成一个新的快照,然后使用该 Snapshot 来评估用于测试的 selectors。

示例: Jest 单元测试 selectors#

const numberState = atom({key: 'Number', default: 0});
const multipliedState = selector({  key: 'MultipliedNumber',  get: ({get}) => get(numberState) * 100,});
test('Test multipliedState', () => {  const initialSnapshot = snapshot_UNSTABLE();  expect(initialSnapshot.getLoadable(multipliedState).valueOrThrow()).toBe(0);
  const testSnapshot = snapshot_UNSTABLE(({set}) => set(numberState, 1));  expect(testSnapshot.getLoadable(multipliedState).valueOrThrow()).toBe(100);})