您如何使用 Jest 模拟 Firebase Firestore 方法? [英] How do you mock Firebase Firestore methods using Jest?

查看:18
本文介绍了您如何使用 Jest 模拟 Firebase Firestore 方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列函数,每个函数都执行各种 Firestore 交互.我如何使用 Jest 来模拟这些 firestore 调用?我想避免使用图书馆.

I have a series of functions, each performing various firestore interactions. How do I use Jest to mock these firestore calls? I would like to avoid using a library.

当我使用 jest.mock("firebase/app")jest.mock("firebase/firestore") 和其他变体时,我要么得到 null TypeErrors, 或错误表明我仍在引用实际导入而不是模拟:Error: ... 确保您调用 initializeApp().

When I use jest.mock("firebase/app") and jest.mock("firebase/firestore") and other variations, I either get null TypeErrors, or errors indicating I am still referencing the actual import and not the mock: Error: ... make sure you call initializeApp().

例如我要测试的一个简单函数:

For example, a simple function I want to test:

import firebase from "firebase/app";
import "firebase/firestore";

export const setDocData = (id, data) => {
  const newDoc = {
    created: firebase.firestore.FieldValue.serverTimestamp(),
    ...data
  };
  firebase
    .firestore()
    .doc("docs/" + id)
    .set(newDoc);
};

注意 firebase 是如何像往常一样导入的,然后 firestore 的导入会产生副作用.还要注意 firestore 首先作为函数被调用,然后作为属性被引用.我相信这是我麻烦的根源.

Notice how firebase is imported as usual, then firestore is imported a side effect. Also notice how firestore is called first as a function, then later referenced as a property. I believe this is the source of my trouble.

推荐答案

这是我找到的解决方案.网上关于这方面的资料不多,希望对大家有所帮助.

Here is the solution I have found. There isn't much information online about this, so I hope it helps someone.

我相信你可以使用 jests /__MOCKS__/ 做类似的事情文件夹系统,而不是像我这样覆盖 firestore 对象示例.

I believe you can do something similar using jests /__MOCKS__/ folders system, rather than overwriting the firestore object as I do in this example.

诀窍是创建模拟函数的链式 API,并将其设置在 firebase 对象上,而不是导入和模拟 firestore.下面的示例允许我测试上面的示例函数,以及 doc().get() 承诺.

The trick is to create a chained API of mock functions, and set this on the firebase object, instead of importing and mocking firestore. The example below allows me to test the above example function, and also doc().get() promises.

const docData = { data: "MOCK_DATA" };
const docResult = {
  // simulate firestore get doc.data() function
  data: () => docData
};
const get = jest.fn(() => Promise.resolve(docResult));
const set = jest.fn();
const doc = jest.fn(() => {
  return {
    set,
    get
  };
});
const firestore = () => {
  return { doc };
};
firestore.FieldValue = {
  serverTimestamp: () => {
    return "MOCK_TIME";
  }
};

export { firestore };

我在所有测试执行之前运行的文件中声明它(参见文档),并在我的测试文件中导入和使用它,如下所示:

I declare it in a file that runs before all my tests do (see docs), and import and use it in my test files like this:

import firebase from "firebase/app";
import { firestore } from "../setupTests";
firebase.firestore = firestore;

describe("setDocData", () => {
  const mockData = { fake: "data" };
  beforeEach(() => {
    jest.clearAllMocks();
    setDocData("fakeDocID", mockData);
  });

  it("writes the correct doc", () => {
    expect(firestore().doc).toHaveBeenCalledWith("docs/fakeDocID");
  });

  it("adds a timestamp, and writes it to the doc", () => {
    expect(firestore().doc().set).toHaveBeenCalledWith({
      created: "MOCK_TIME",
      fake: "data"
    });
  });
});

这篇关于您如何使用 Jest 模拟 Firebase Firestore 方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆