如何测试从firestore获取数据的react组件



有人告诉我,我们应该使用模拟数据,而不是与真实的数据库资源交互。

我还被告知,我应该"模拟firebase对象并从中返回伪造的结果">,但是我在哪里模拟firebase对象,它是我的实际组件还是在我的测试文件中,我如何实际模拟它?

这是我的代码:

// just a hook that fetches current user data
export const useGetCurrentUsersProfile = () => {
const userInfoRef = doc(firestore, "users", auth.currentUser?.uid ?? "_STUB_");
return useFirestoreDocument(
["userInfo"],
userInfoRef,
{
subscribe: false,
},
{
select: (data) => {
const currentUsersProfile = data.data() as UserInfo;
return currentUsersProfile;
},
enabled: !!auth.currentUser?.uid,
}
);
};

我的react组件使用该钩子获取数据:

import React from "react";
import { useGetCurrentUsersProfile } from "../app/utilityfunctions";
function Siuu() {
const { data: currentUser } = useGetCurrentUsersProfile();
return (
<div>
<div>{currentUser?.name}</div>
</div>
);
}
export default Siuu;
/** @jest-environment jsdom */
import { render, screen } from "@testing-library/react";
import Siuu from "./siuu";
test("renders component", () => {
render(<Siuu />);
const randomElement = screen.getByText(/Jack/i);
expect(randomElement).toBeInTheDocument();
});

如果我只是想从挂钩返回这些数据,我该在哪里以及如何嘲笑它:

{姓名:"jack",电子邮箱:"jack@gmail.com"}

模拟是在测试代码中完成的,而不是在真正的应用程序代码中。

它的意思是:你创建了一个东西的假版本,这样当测试让应用程序做一些事情时,真实的东西就不会被使用。Jest有一些工具可以帮助你做到这一点。

在您的案例中,您应该模拟的似乎是doc和/或useFirestoreDocument函数。您的代码示例没有说明这两个东西是从哪里来的,而且我不知道firestore,所以我只假设这两个都是从单个"导入的;一些消防仓库pkg"这样的包装:import { doc, useFirestoreDocument } from 'some-firestore-pkg'

最简单的方法是专门为这个测试创建一个一次性的mock,但如果这个firestore的东西是通过应用程序使用的,并且你想为其余的测试编写测试,你会想了解Jest为创建可重复使用的mock提供的工具和模式。对于这个答案,我将使用一次性模拟来完成所有操作。

/*
STEP 1: Import some-firestore-pkg package so we can manipulate it during the
tests. This will be the real firestore package.
*/
import firestorePkg from 'some-firestore-pkg'
// ...skipping down to your test
test("renders component", () => {
/*
STEP 2: replace the real `doc` function with a fake version that returns a
hard-coded value.

We MUST replace it to prevent the real one from doing any real work,
although we may not need to make the fake version return anything. But,
let's do so, in order to miminize the chance that this test will stop
working when the hook is modified in the future to verify the results of
each operation.
*/
let docSpy = jest.spyOn(firestorePkg, 'doc').mockReturnValue(
'A_FAKE_USER_INFO_REF'
)
// now, when the real hook calls the doc(...) function, it will get that value

/*
STEP 3: replace the real useFirestoreDocument with a fake version that
returns the hard-coded fake data that you want the app to receive during the
test. You can probably guess what this will look like:
*/
let useDocSpy = jest.spyOn(firestorePkg, 'useFirestoreDocument').mockReturnValue(
{ data: { name: "jack", email: "jack@gmail.com" } }
)

/*
STEP 4: now that we've "arranged," let's "act" and then "assert"
*/
let app = render(<Siuu />)
let randomElement = app.getByText(/Jack/i)
expect(randomElement).toBeInTheDocument()

// STEP 5: completely remove our fake versions so other tests aren't impacted
docSpy.mockRestore()
useDocSpy.mockRestore()
})

最新更新