代码之家  ›  专栏  ›  技术社区  ›  Cameron Hotchkies

在react native中使用jest模拟和监视键盘事件

  •  3
  • Cameron Hotchkies  · 技术社区  · 6 年前

    给出以下代码:

    import { Keyboard } from 'react-native';
    
    // ....
    
    componentDidMount() {
      this.keyboardShowListener = Keyboard.addListener(
        'keyboardWillShow',
        () => this.setState({ visible: true }),
      );
      this.keyboardHideListener = Keyboard.addListener(
        'keyboardWillHide',
        () => this.setState({ visible: false }),
      );
    }
    
    // ....
    
    onCancel() {
      const { clearActiveInput } = this.props;
      clearActiveInput();
      Keyboard.dismiss();
    }
    

    Keyboard dismiss() 事件已触发?

    0 回复  |  直到 6 年前
        1
  •  2
  •   Community CDub    4 年前

    订阅的组件也遇到了类似的问题 Keyboard 事件

    const MyComponent = () => {
        useEffect(() => {
            const listener = Keyboard.addListener('keyboardDidHide', () => {})
    
            return () => {
                listener.remove()
            }
        })
    
        return <View>...</View>
    }
    

    我可以测试 Keyboard.addListener 进行以下测试,并测试 listener.remove 在组件卸载时调用

    import renderer from 'react-test-renderer'
    
    const mockListener = {
        remove: jest.fn(),
    }
    const originalAddListener = Keyboard.addListener
    const mockAddListener = jest.fn().mockReturnValue(mockListener)
    
    describe('<MyComponent />', () => {
        beforeAll(() => {
            Keyboard.addListener = mockAddListener
        })
        beforeEach(() => {
            mockAddListener.mockClear()
            mockListener.remove.mockClear()
        })
        afterAll(() => {
            Keyboard.addListener = originalAddListener
        })
        it('should subscribe to KeyboardDidClose event', () => {
            renderer.create(<MyComponent />)
            expect(Keyboard.addListener).toHaveBeenCalled()
        })
    
        it('should call listener.remove on unmount', () => {
            const component = renderer.create(
                < MyComponent />,
            )
            component.unmount()
            expect(mockListener.remove).toHaveBeenCalled()
        })
    })
    
        2
  •  3
  •   Thiago de Oliveira Cruz    4 年前

    所以这个问题更复杂,我一开始就可以想象解决。

    因此0.63和0.62的事件和侦听器是 https://reactnative.dev/docs/keyboard#docsNav

    useEffect(() => {
       Keyboard.addListener("keyboardDidShow", _keyboardDidShow);
       Keyboard.addListener("keyboardDidHide", _keyboardDidHide);
    
       // cleanup function
       return () => {
           Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
           Keyboard.removeListener("keyboardDidHide", _keyboardDidHide);
       };
    }, []);
    
    const _keyboardDidShow = () => {
        alert("Keyboard Shown");
    };
    
    const _keyboardDidHide = () => {
        alert("Keyboard Hidden");
    };
    

    让Jest调用这两个函数 _keyboardDidShow _keyboardDidHide 你需要使用 Keyboard.emit('_keyboardDidShow')

    例子:

    it('Test Keyboards keyboardDidShow is called', () => {
        const { getByTestId } = render(<Container />);
        act(() => {
            Keyboard.emit('keyboardDidShow', {});
        });
        const box = getByTestId('TEST');
        //Do here your expect clauses to check if something changed in your container
    });