Как издеваться над объектом курсора Монго с помощью Node.js и Синон

#node.js #mongodb #sinon

Вопрос:

Мне нужно добавить покрытие модульного тестирования в какой-то старый код, и мне трудно создать макет объекта курсора, который позволит связать проект, ограничить, пропустить, отобразить, как показано ниже.

 collection.find({}, (err, res) => {
......
    const results = res.project(projection)
                       .limit(limitCount)
                       .skip(skipCount)
                       .toArray()
 

Я издевался над DB/collection/find раньше с помощью toArray, доступного для объекта ответа (что-то вроде приведенного ниже), но не уверен, как обрабатывать цепочку других «значений» курсора, упомянутых выше.

             let fakeFind = () => {
                return {
                    toArray: () => {
                        return Promise.resolve(testCustomerRecord);
                    }
                };
            }

            let stubFind = sinon.stub().callsFake(fakeFind);
            
            let mockDb = {
                collection: () => {
                    return {
                        find: stubFind
                    };
                }
            };
 

Я попытался добавить их в качестве свойств, функций, но получил такую ошибку:

Ошибка типа: item.project(…).ограничение не является функцией

Любые советы приветствуются!

Ответ №1:

stub.returnsThis(); метод позволяет блокировать вызовы цепочки.

Напр.

 import sinon from 'sinon';

// service under test
const service = {
  find(db) {
    return new Promise((resolve) => {
      db.collection.find({}, (err, res) => {
        const results = res.project({ a: 1 }).limit(10).skip(0).toArray();
        resolve(results);
      });
    });
  },
};

describe('68483854', () => {
  it('should pass', async () => {
    const mockRes = {
      project: sinon.stub().returnsThis(),
      limit: sinon.stub().returnsThis(),
      skip: sinon.stub().returnsThis(),
      toArray: sinon.stub().returns('mock data'),
    };
    const mockDb = {
      collection: {
        find: sinon.stub().callsFake((where, callback) => {
          callback(null, mockRes);
        }),
      },
    };
    const actual = await service.find(mockDb);
    sinon.assert.match(actual, 'mock data');
    sinon.assert.calledWithExactly(mockRes.project, { a: 1 });
    sinon.assert.calledWithExactly(mockRes.limit, 10);
    sinon.assert.calledWithExactly(mockRes.skip, 0);
    sinon.assert.calledOnce(mockRes.toArray);
  });
});
 

Комментарии:

1. Спасибо, удивлен, что я не наткнулся на это раньше в своих поисках!