reactjs - 由于 : FIRESTORE (9. 6.1) 内部断言失败,无法编写 firestore 测试:意外状态

标签 reactjs firebase unit-testing google-cloud-firestore jestjs

是否可以使用 Firebase Firestore 进行测试?我一直在关注测试教程,并且测试对其他人有用但对我不起作用。

我的组件代码在客户端工作,所以我很困惑为什么会收到此错误。

我只找到了有关在 firebase 中测试安全规则的信息,但没有找到有关 firestore 的信息,这是否意味着它是我们唯一可以测试的东西?

这是我得到的错误:

    FIRESTORE (9.6.1) INTERNAL ASSERTION FAILED: Unexpected state

      at fail (node_modules/@firebase/firestore/src/util/assert.ts:40:9)
      at hardAssert (node_modules/@firebase/firestore/src/util/assert.ts:54:5)
      at fromBytes (node_modules/@firebase/firestore/src/remote/serializer.ts:252:5)
      at fromWatchChange (node_modules/@firebase/firestore/src/remote/serializer.ts:475:25)
      at PersistentListenStream.onMessage (node_modules/@firebase/firestore/src/remote/persistent_stream.ts:642:25)
      at node_modules/@firebase/firestore/src/remote/persistent_stream.ts:517:21
      at node_modules/@firebase/firestore/src/remote/persistent_stream.ts:570:18
      at node_modules/@firebase/firestore/src/util/async_queue_impl.ts:135:7
      at node_modules/@firebase/firestore/src/util/async_queue_impl.ts:186:14

● if the user is fetched, the name is shown

    Unable to find an element with the text: /James/i. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

我的组件代码:

function Hellopage() {
  const [userData, setUserData] = useState();

  const getData = async () => {
    const docRef = doc(firestore, "users", "pW5CizOJOpXezr5lGGshDmKdVzZ2");
    const docSnap = await getDoc(docRef);
    if (docSnap.exists()) {
      setUserData(docSnap.data());
    } else {
      // doc.data() will be undefined in this case
      console.log("No such document!");
    }
  };

  useEffect(() => {
    getData();
  }, []);

  return (
    <div>
      <div>{userData?.name}</div>
    </div>
  );
}

export default Hellopage;

我的测试:

test("if the user is fetched, the name is shown", async () => {
  const result = render(<HelloPage />);

  expect(await result.findByText(/James/i)).toBeInTheDocument();
});

最佳答案

这是 jsdom 测试环境的问题。使用 firestore 时应将环境切换回默认的 node。如果您依赖于 jsdom 进行其他测试,最简单的方法可能是在文件顶部使用文档 block :

/**
 * @jest-environment node
 */

编辑 - 分离和模拟

您可能会遇到此特定测试的问题,因为 React 和 firebase 紧密耦合,React 需要 jsdom 而 firebase 需要 node。这可以通过使用实际的基于 DOM 的测试环境(如 cypress)来解决,或者通过提取函数和使用模拟来单独测试 firebase 和 react。第二种方法更好,因为它意味着在测试 ui 时不会访问数据库:

//firebaseService.ts

const getData = async()=>{
    const docRef = doc(firestore, "users", "pW5CizOJOpXezr5lGGshDmKdVzZ2");
    const docSnap = await getDoc(docRef);
    if (docSnap.exists()) {
      return docSnap.data();
    } else {
      console.log("No such document!");
    }
}

//Hellopage.tsx

function Hellopage({getData}) {
  const [userData, setUserData] = useState();
  useEffect(() => {
    getData()
      .then(data=> data && setUserData(data))
  }, []);

  return (
    <div>
      <div>{userData?.name}</div>
    </div>
  );
}

//Hellopage.test.tsx

const mockGetData = ()=>
  ({name:"foo"})

test('hello page renders text', () => {
  const component = renderer.create(<Hellopage getData={mockGetData}/>)
  ...
})

//firebaseService.test.ts

test('firebase service gets user data', async () => {
  const data = await getData()
  ...
})

关于reactjs - 由于 : FIRESTORE (9. 6.1) 内部断言失败,无法编写 firestore 测试:意外状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70327245/

相关文章:

database - playframework: -- 数据库/测试框架/缓存错误

javascript - 类型错误 : Illegal Invocation

firebase - Flutter 和 google_sign_in 插件 : PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException : 10: , null)

javascript - 如何在 firebase 上获取当前用户

firebase - Firebase 云消息服务中的多播 ID

java - 如何在android sdk上使用PowerMock

sqlite - 使用 SqlCe 作为数据库并使用 Sqlite 进行单元测试

javascript - React 组件不渲染来自父级的 Prop

javascript - 如何使用 moment 获取重复日期

reactjs - 在 React 应用程序中运行 npm start 时出现 babel-jest 依赖问题