首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用RTK-Query useLazyQuery和ReactNative时,开玩笑没有正确退出。

在使用RTK-Query useLazyQuery和ReactNative时,开玩笑没有正确退出。
EN

Stack Overflow用户
提问于 2021-10-12 09:48:42
回答 1查看 865关注 0票数 0

我正在尝试测试我用RTK-Query编写的一些功能。我使用createApi创建了一个api,并导出了useLazyQuery钩子。我调用这个钩子,然后侦听useEffect钩子中的结果更改。这与应用程序中的工作原理一样。当我尝试使用msw和@/react为这个逻辑编写测试时,我遇到了错误。

当我运行测试时,我看到以下控制台输出:

代码语言:javascript
复制
Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

探测到标志没有帮助。

我的测试看起来如下:

代码语言:javascript
复制
const server = setupServer();
const mockedNavigate = jest.fn();

jest.mock('@react-navigation/native', () => {
  return {
    ...jest.requireActual('@react-navigation/native'),
    useNavigation: () => ({
      navigate: mockedNavigate,
    }),
  };
});

describe('ForgotPasswordForm', () => {
  const storeRef = setupApiStore(forgotPasswordApi);

  const testRender = () =>
    render(
      <Provider store={storeRef.store}>
        <ForgotPasswordForm />
      </Provider>
    );

  beforeAll(() => {
    jest.spyOn(Alert, 'alert');
    server.listen();
  });

  beforeEach(() => {
    storeRef.store.dispatch(forgotPasswordApi.util.resetApiState());
  });

  afterEach(() => {
    jest.resetAllMocks();
    server.resetHandlers();
    cleanup();
  });

  afterAll(() => {
    server.close();
  });

  it('should display an error alert if the email is not registered', async () => {
    server.use(
      rest.get(`${API_ENDPOINT}/ResetPassword`, (_, res, ctx) =>
        res(ctx.status(200), ctx.json({ status: 'error' }))
      )
    );

    const { getByText, getByPlaceholderText } = testRender();

    fireEvent.changeText(
      getByPlaceholderText('Registered email address'),
      'unregistered@test.com'
    );

    fireEvent.press(getByText(/Retrieve Password/i));

    await waitFor(() =>
      expect(Alert.alert).toHaveBeenCalledWith(
        'Error',
        'An error has occured. Please contact us for help.'
      )
    );
  });
});

我的API如下所示:

代码语言:javascript
复制
export const forgotPasswordApi = createApi({
  reducerPath: 'forgotPassword',
  baseQuery: fetchBaseQuery({
    baseUrl: API_ENDPOINT,
  }),
  endpoints: (builder) => ({
    resetPassword: builder.query({
      query: (email) => ({
        url: '/ResetPassword',
        params: { email },
      }),
    }),
  }),
});

export const { useLazyResetPasswordQuery } = forgotPasswordApi;

我的组件看起来如下:

代码语言:javascript
复制
const ForgotPasswordForm = () => {
  const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();

  const [email, setEmail] = useState('');
  const [showInvalidEmailMessage, setShowInvalidEmailMessage] = useState(false);

  const handleEmailChange = (value: string) => {
    setEmail(value);
  };

  const [triggerResetPasswordQuery, results] = useLazyResetPasswordQuery();

  useEffect(() => {
    if (results.isUninitialized || results.isFetching) return;

    if (results?.data?.status === 'error') {
      Alert.alert('Error', 'An error has occured. Please contact us for help.');
    } else {
      Alert.alert('An email has been sent with further instructions.');
    }
  }, [results]);

  const handleForgotPassword = () => {
    const isEmailFormatValid = /^\S+@\S+\.\S+$/.test(email);

    if (isEmailFormatValid) {
      setShowInvalidEmailMessage(false);
      triggerResetPasswordQuery(email);
    } else {
      setShowInvalidEmailMessage(true);
    }
  };

  return (
    <>
      <Wrapper width="100%" mt={40} mb={20}>
        <TextInput
          value={email}
          placeholder="Registered email address"
          handleOnChangeText={handleEmailChange}
          accessibilityLabel="forgot-password-email"
        />
      </Wrapper>
      <Wrapper mb={10} width="100%">
        <Button
          fullWidth
          title="Retrieve Password"
          onPress={handleForgotPassword}
        />
      </Wrapper>
      {results.isLoading && <LoadingOverlay text="Sending Email" />}
    </>
  );
};

export default ForgotPasswordForm;

谢谢。

EN

回答 1

Stack Overflow用户

发布于 2022-01-16 21:28:57

我面临着类似的问题,但在我的例子中,我没有使用RTK查询生成的钩子的惰性版本。我通过阻止API在测试环境中运行代码时保存数据来修正它。我的解决方案的代码示例:

代码语言:javascript
复制
const api = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({
    baseUrl: 'any-base-url',
  }),
  keepUnusedDataFor: process.env.NODE_ENV !== 'test' ? 60 : 0, // <- here
  endpoints: () => {
    return {
      // your endpoints
    };
  },
});

参考keepUnusedDataForhttps://redux-toolkit.js.org/rtk-query/api/createApi#keepunuseddatafor

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69538390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档