为什么 jest mock 没有模拟 Firestore 集合的 onSnapshot 函数?

Why jest mock is not mocking up a Firestore collection onSnapshot function?

如标​​题所述,我不知道为什么函数 Database.collection(...).onSnapshot 方法没有作为函数使用。

我收到的消息错误是:TypeError: Database.collection(...).onSnapshot is not a function

我正在尝试让它像这样工作:

  test.only('should react when a new record is created', async () => {
    jest.mock('@google-cloud/firestore', () => jest.fn(() => ({
      collection: jest.fn()
        .mockImplementationOnce(function () { return this })
        .mockImplementationOnce(function () { return this })
        .mockImplementationOnce(function () { return this })
        .mockImplementationOnce(function () { return this })
        .mockImplementationOnce(function () { return this })
        .mockImplementationOnce(function () { return this })
        .mockResolvedValueOnce(() => {
          return {
            onSnapshot: () => {} // HOW TO MAKE IT WORK AS A FUNCTION?
          }
        }),
      get: jest.fn().mockResolvedValue({ docs: [] }),
      doc: jest.fn().mockReturnThis(),
      set: jest.fn().mockReturnThis(),
      limit: jest.fn().mockReturnThis(),
      select: jest.fn().mockReturnThis()
    })))

    const StatisticsService = require('./index')

    await StatisticsService()
  })
代码逻辑:
const Firestore = require('@google-cloud/firestore')
const Database = new Firestore()

const collections = ['products', 'users', 'orders']

collections.forEach(collection => {
  Database.collection(collection).onSnapshot(snapshot => {
    console.log('', snapshot)
    snapshot.docChanges().forEach(change => {
      if (change.type === 'added') this.onDatabaseRecordCreated(collection, change.doc.data())
      if (change.type === 'modified') this.onDatabaseRecordUpdated(collection, change.doc.data())
      if (change.type === 'removed') this.onDatabaseRecordRemoved(collection, change.doc.data())
    })
  }, error => {
    console.error(error)
  })
})

试试这个:

index.js:

const Firestore = require('@google-cloud/firestore');
const Database = new Firestore();

async function StatisticsService() {
  const collections = ['products', 'users', 'orders'];
  collections.forEach((collection) => {
    Database.collection(collection).onSnapshot(
      (snapshot) => {
        // console.log('', snapshot);
        snapshot.docChanges().forEach((change) => {
          console.log(change);
        });
      },
      (error) => {
        console.error(error);
      }
    );
  });
}

module.exports = StatisticsService;

index.test.js:

describe('71115363', () => {
  test('should pass', async () => {
    jest.mock('@google-cloud/firestore', () => {
      const mChanges = [{ name: 'fake data' }];
      const mSnapshot = {
        docChanges: jest.fn().mockReturnValue(mChanges),
      };
      return jest.fn(() => ({
        collection: jest.fn().mockReturnThis(),
        onSnapshot: jest.fn().mockImplementation((callback) => {
          callback(mSnapshot);
        }),
      }));
    });

    const StatisticsService = require('./index');

    await StatisticsService();
  });
});

测试结果:

 PASS  Whosebug/71115363/index.test.js
  71115363
    ✓ should pass (103 ms)

  console.log
    { name: 'fake data' }

      at Whosebug/71115363/index.js:8:17
          at Array.forEach (<anonymous>)

  console.log
    { name: 'fake data' }

      at Whosebug/71115363/index.js:8:17
          at Array.forEach (<anonymous>)

  console.log
    { name: 'fake data' }

      at Whosebug/71115363/index.js:8:17
          at Array.forEach (<anonymous>)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.184 s, estimated 2 s