How do you mock Firebase Firestore methods using Jest?

前端 未结 7 1767
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-17 17:12

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.

7条回答
  •  遥遥无期
    2020-12-17 17:59

    If mocking seems tedious, don't. Use the emulators.

    I believe this is a relatively new option for handling reads & writes in testing, so I'm posting it. Here's a quick walk-through.

    1. Download firebase CLI tools.
    $ curl -sL firebase.tools | bash
    
    1. Initialize firebase in your project if you haven't already. Just choose firestore to get started unless you know you'll need the others.
    $ firebase init
    
    1. Configure your firestore instance to point to the emulators (you should be able to mock db for one that redirects to the emulator, but this way will allow you to read/write to the emulator in your development environment also).
    const db = firebase.initializeApp(config).firestore()
    if (location.hostname === "localhost") {
      db.settings({
        host: "localhost:8080",
        ssl: false
      });
    }
    
    1. Start the emulator. There's also a command that runs the emulators for the duration of a shell command, which you can add to your test suite npm script if you'd like.
    $ firebase emulators:start
    
    1. Test something that uses firestore.
      describe('New city', () => {
        it('should create a new city in firestore', async () => {
          await db.collection('cities').doc('Seattle').set({ state: "WA" })
          const city = await db.collection('cities').doc("Seattle").get()
    
          expect(city.data()['population']).toEqual("WA")
        })
      })
    
    1. Optional: Create a db cleanup function that uses the emulator's rest endpoint to remove data between tests.
    async function cleanFirestore() {
      const Http = new XMLHttpRequest();
      const url = "http://localhost:8080/emulator/v1/projects//databases/(default)/documents"
    
      Http.open("DELETE", url);
      Http.send();
    
      return new Promise((resolve, reject) => {
        setTimeout(reject, 2000)
        Http.onreadystatechange = resolve
      })
    }
    

    For an emulator walkthrough guide from Google: https://google.dev/pathways/firebase-emulators

    Docs: https://firebase.google.com/docs/emulator-suite

提交回复
热议问题