如何用 Sinon 模拟 Firebase set()?

How to mock a Firebase set() with Sinon?

我正在尝试测试这个 Firebase 访问代码

let writeHomePromise = admin
  .database()
  .ref(
    "sm_matches/" +
    match.date +
    "/" +
    match.homeTeam.name +
    "/homeNGSPlayers"
  )
  .set(match.homePlayers);

使用诗乃。

我创建了一个匹配

    const match = {
        'date' : '2902199',
        'homeTeam' : '{"name" : "My_team"}',
        'homePlayers'  : ["Nomran Mailer", "Peter Bonetti"],
        'awayPlayers': ["Ernst Blofeld", "Postman Pat"],
      };

我正在尝试用

模拟该代码,但没有成功
    let refStub = sinon.stub();
    let setStub = sinon.stub();
    refStub.withArgs('sm_matches/2902199/My_team/homeNGSPlayers').returns(
        {push: () => ({key: 'fakeKey', set: setStub})}
        );

这给了我 TypeError: Cannot read property 'set' of undefined.

这是我第一次涉足 Sinon,即使是这么简单的事情也给我带来了问题。

我做错了什么?

我认为您应该在使用任何 Firebase 服务之前致电 admin.initializeApp()。以下示例使用 offline mode 测试策略。

Write siloed and offline unit tests with no side effects. This means that any method calls that interact with a Firebase product (e.g. writing to the database or creating a user) need to be stubbed. Using offline mode is generally not recommended if you have Cloud Firestore or Realtime Database functions, since it greatly increases the complexity of your test code.

尝试这样的存根方法:

index.js:

const admin = require('firebase-admin');

admin.initializeApp();

function main() {
  const match = {
    date: '2902199',
    homeTeam: { name: 'My_team' },
    homePlayers: ['Nomran Mailer', 'Peter Bonetti'],
    awayPlayers: ['Ernst Blofeld', 'Postman Pat'],
  };
  return admin
    .database()
    .ref('sm_matches/' + match.date + '/' + match.homeTeam.name + '/homeNGSPlayers')
    .set(match.homePlayers);
}

module.exports = main;

index.test.js:

const sinon = require('sinon');
const admin = require('firebase-admin');

describe('71267791', () => {
  it('should pass', async () => {
    const adminInitStub = sinon.stub(admin, 'initializeApp');
    const databaseService = {
      ref: sinon.stub().returnsThis(),
      set: sinon.stub(),
    };
    const databaseStub = sinon.stub().returns(databaseService);

    Object.defineProperty(admin, 'database', { get: () => databaseStub });
    const main = require('./');
    await main();
    sinon.assert.calledOnce(adminInitStub);
    sinon.assert.calledOnce(admin.database);
    sinon.assert.calledWithExactly(databaseService.ref, 'sm_matches/2902199/My_team/homeNGSPlayers');
    sinon.assert.calledWithExactly(databaseService.set, ['Nomran Mailer', 'Peter Bonetti']);
  });
});

测试结果:

  71267791
    ✓ should pass (655ms)


  1 passing (661ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.js |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------

包版本:

"firebase-admin": "^10.0.2",