5

我围绕 ScrollView 编写了一个简单的包装组件,它根据给定的可用高度启用/禁用滚动:

import React, {useCallback, useEffect, useRef, useState} from 'react';
import {Keyboard, ScrollView} from 'react-native';
import {deviceHeight} from '../../../platform';

export default function ScrollingForm({
  availableHeight = deviceHeight,
  children,
}) {
  const [scrollEnabled, setScrollEnabled] = useState(true);
  const [formHeight, setFormHeight] = useState(0);
  const scrollingForm = useRef(null);

  const checkScrollViewEnabled = useCallback(() => {
    setScrollEnabled(formHeight > availableHeight);
  }, [availableHeight, formHeight]);

  const onFormLayout = async event => {
    await setFormHeight(event.nativeEvent.layout.height);
    checkScrollViewEnabled();
  };

  useEffect(() => {
    Keyboard.addListener('keyboardDidHide', checkScrollViewEnabled);

    // cleanup function
    return () => {
      Keyboard.removeListener('keyboardDidHide', checkScrollViewEnabled);
    };
  }, [checkScrollViewEnabled]);

  return (
    <ScrollView
      ref={scrollingForm}
      testID="scrollingForm"
      keyboardDismissMode="on-drag"
      keyboardShouldPersistTaps="handled"
      scrollEnabled={scrollEnabled}
      onLayout={onFormLayout}
      onKeyboardDidShow={() => setScrollEnabled(true)}>
      {children}
    </ScrollView>
  );
}

我需要为此组件编写单元测试。到目前为止,我有:

import React from 'react';
import {Keyboard} from 'react-native';
import {render} from 'react-native-testing-library';
import {Text} from '../..';
import ScrollingForm from './ScrollingForm';

describe('ScrollingForm', () => {
  Keyboard.addListener = jest.fn();
  Keyboard.removeListener = jest.fn();

  let renderer;
  describe('keyboard listener', () => {
    it('renders text with default props', () => {
      renderer = render(
        <ScrollingForm>
          <Text>Hello World!</Text>
        </ScrollingForm>,
      );
      expect(Keyboard.addListener).toHaveBeenCalled();
    });

    it('should call listener.remove on unmount', () => {
      renderer = render(
        <ScrollingForm>
          <Text>Goodbye World!</Text>
        </ScrollingForm>,
      );
      renderer.unmount();
      expect(Keyboard.removeListener).toHaveBeenCalled();
    });
  });
});

我还想确认,如果可用高度大于表单高度,则在布局上,scrollEnabled 正确设置为 false。我试过这样的事情:

it('sets scrollEnabled to false onFormLayout width 1000 height', () => {
  mockHeight = 1000;
  const {getByTestId} = render(
    <ScrollingForm availableHeight={500}>
      <Text>Hello World!</Text>
    </ScrollingForm>,
  );
  const scrollingForm = getByTestId('scrollingForm');

  fireEvent(scrollingForm, 'onLayout', {
    nativeEvent: {layout: {height: mockHeight}},
  });
  expect(scrollingForm.props.scrollEnabled).toBe(false);
});
4

0 回答 0