开玩笑:尝试模拟异步存储时无法读取未定义的属性(读取“getItem”)

问题描述 投票:0回答:1

我正在努力让我的笑话规范与

AsyncStorage
一起工作。我按照 Jest 与异步存储集成 的指南进行操作,并使用该指南设置模拟目录。这使我的项目结构看起来像这样...... project structure showing the mocks folder.

我的

async-storage.js
有以下内容...

export * from "@react-native-async-storage/async-storage/jest/async-storage-mock";

我试图测试的规范是检查我是否根据从存储中检索的值将用户重定向到某个页面。这就是规范的设置方式(请原谅,它是目前最好看的 - 只是想让测试暂时正常工作!)...

import { render, waitFor } from "@testing-library/react-native";
import AsyncStorage from "@react-native-async-storage/async-storage/jest/async-storage-mock";
import { useRouter } from "expo-router";

import Index from "@/src/app/index";

jest.mock("expo-router", () => ({
  useNavigation: jest.fn(),
  useFocusEffect: jest.fn().mockImplementation((callback) => callback()),
  useRouter: jest.fn()
}));

describe("Index page", () => {
  const mockRouter = {
    replace: jest.fn()
  }
  ;(useRouter as jest.Mock).mockReturnValue(mockRouter)

  async function asyncOperationOnAsyncStorage(firstTime: string){
    await AsyncStorage.setItem("firstTime", firstTime)

    await AsyncStorage.getItem("firstTime")
  }

  it("renders successfully", async () => {
    render(<Index />);
  });

  it("redirects to 'First Launch' page when the user opens the app for the first time", async () => {
    await asyncOperationOnAsyncStorage("");
    render(<Index />);

    await waitFor(() => {
      expect(mockRouter.replace).toHaveBeenCalledWith("/first-launch");
    })
  })

  it("redirects to 'Login' page when it is not the user's first time using the app", async () => {
    await asyncOperationOnAsyncStorage("DONE");

    render(<Index />);

    await waitFor(() => {
      expect(mockRouter.replace).toHaveBeenCalledWith("/login");
    })
  })

索引页的编码如下...

import { View, Text } from 'react-native';
import { useFocusEffect, useRouter } from "expo-router";
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useCallback } from 'react';

export default function Index() {
  const router = useRouter();

  const handleRedirect = async () => {
    try {
      const firstTime = await AsyncStorage.getItem("firstTime");
      
      if (firstTime !== "DONE") {
        router.replace("/first-launch");
      else {
        router.replace("/login");
      }
    } catch (error) {
      console.log("Cannot retrieve data from storage", error);
      router.replace("/first-launch");
    }
  }

  useFocusEffect(
    useCallback(() => {
      handleRedirect()
    }, [handleRedirect])
  );

  return (
    <View>
      <Text>Redirecting...</Text>
    </View>
  );
}

我以为我的异步设置正确,但是每当我运行测试时,我都会在控制台中收到此错误...

Cannot retrieve data from storage TypeError: Cannot read properties of undefined (reading 'getItem')

这意味着在运行我的

getItem
index
函数时执行异步的
handleRedirect()
时,规范会失败。当我运行应用程序时,不会发生此错误,因此我认为我一定没有正确设置 Jest 和异步存储集成 - 但我不知道哪里出了问题!

预先感谢您的帮助!

reactjs react-native unit-testing jestjs asyncstorage
1个回答
0
投票

问题现在似乎已经解决了。解决方法是将我的

async-storage.js
更改为...

import AsyncStorage from "@react-native-async-storage/async-storage/jest/async-storage-mock";
export default AsyncStorage;

...然后将我的

AsyncStorage
规格文件上的
index
的导入更改为
import AsyncStorage from "@react-native-async-storage/async-storage/jest/async-storage-mock";

© www.soinside.com 2019 - 2024. All rights reserved.