【问题标题】:How to mock useEffect async calls with react-native-testing-library?如何使用 react-native-testing-library 模拟 useEffect 异步调用?
【发布时间】:2022-01-27 21:35:49
【问题描述】:

我正在尝试使用以下内容测试具有 useEffect 挂钩的屏幕:

export const SomeScreen: React.FC<Props> = ({}) => {

  const [isSensorAvailable, setIsSensorAvailable] = useState(false);

  useEffect(() => {
    const isSensorAvailableCheck = async () => {
      try {
        await FingerprintScanner.isSensorAvailable();
        setIsSensorAvailable(true);
      } catch (error) {
        console.log(error);
      }
    };

    isSensorAvailableCheck();
  }, []);
  
  ...
   Here goes code that renders View if the sensor is available
  ...
}

我正在尝试以下测试:


import {default as FingerprintScannerMock} from 'react-native-fingerprint-scanner';

jest.mock('react-native-fingerprint-scanner');

(FingerprintScannerMock.isSensorAvailable as jest.Mock).mockResolvedValue(true);

const createTestProps = (props: Object) => ({
  navigation: {
    navigate: jest.fn(),
  },
  ...props,
});

describe('Testing some screen', () => {

   test('testing some functionalities', async () => {
     let props: any;
    props = createTestProps({});

    const component = render(
      <Provider store={store}>
        <RegisterPasswordScreen {...props} />
      </Provider>,
    );

    const {getByText, getByTestId, getAllByTestId} = component;

    const container = getByTestId('containerId');

    expect(container).toBeTruthy();
   });

});

但是这个容器永远找不到,因为 setIsSensorIsAvailable 永远不会将值设置为 true 因为以下错误:

An update to SomeScreen inside a test was not wrapped in act(...).

我什么都试过了:


  const component = await waitFor(() =>
       render(<Provider store={store}>
         <RegisterPasswordScreen {...props} />
        </Provider>,
       );
   ); 

但是当我运行这个测试时,它永远不会结束。还尝试用act(...) 包装它,但这也不起作用,然后错误如下: Can't access .root on unmounted test renderer.

任何帮助表示赞赏,谢谢!

【问题讨论】:

    标签: javascript reactjs react-native jestjs react-native-testing-library


    【解决方案1】:

    有类似的问题

    使用 act(https://reactjs.org/docs/testing-recipes.html#act) 包装组件解决了我的问题

    使用 create 来包装您的组件以进行本机反应,而不是使用包装在 act 中的典型渲染方法

    import { act, create } from 'react-test-renderer';
    
    
    it('test', () => {
        await act(async () => {
            create(<ComponentWithAsyncUseEffect />);
        });
    })
    

    【讨论】:

      【解决方案2】:

      我最终使用了findByTestId 而不是getByTestId,现在它运行良好。

      【讨论】:

      • 对于那些好奇的人,find 工作而不是get 的原因是find 返回一个承诺并重试,直到找到元素或超时。您还可以使用waitFor 来测试具有异步生命周期的组件。详情请见About Queries
      猜你喜欢
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      • 2021-10-22
      • 2020-05-10
      • 2023-03-17
      • 2020-08-31
      • 2021-07-16
      相关资源
      最近更新 更多