Заглушка Sinon JS не работает внутри .on scope - PullRequest
0 голосов
/ 29 мая 2020
it('POST /direct/bulk', function () {
    const file = getFile('notif-direct-bulk.csv')
    sinon.stub(notificationService.constructor.prototype, 'validateNotification').resolves(true)
    sinon.stub(notificationService.constructor.prototype, 'createInAppNotification').resolves(true)
    sinon.stub(fileService.constructor.prototype, 'storeFile').resolves(file.path)
    sinon.stub(fileService.constructor.prototype, 'deleteFile').returns(true)

    notificationService.validateNotification() // it's a stub
     .then((valid) => { 
       return fileService.storeFile() // it's a stub 
     })
     .then((storedFilePath) => {
       const reader = new require('line-by-line')(storedFilePath)
       console.log(notificationService.createInAppNotification()) // it's still a stub 
       console.log(fileService.deleteFile()) // it's still a stub 
       reader
        .on('line', (line) => {
          // inside this scope the stubs are not working
          notificationService.createInAppNotification() // calling the original method, not a stub
        })
        .on('end', () => {
          // inside this scope the stubs are not working
          fileService.deleteFile() // calling the original method, not a stub
        })
     })
})

Почему все заглушки не работают внутри функции .on scope?

Интересно, почему это происходит? Прицелы .on отличаются от прицелов sinon js?

1 Ответ

0 голосов
/ 30 мая 2020

Интересно, все заглушки должны работать, как ожидалось.

Я не знаю вашей реализации, но могу дать вам этот пример, основанный на вашем тестовом коде. Я предполагаю несколько классов (notificationService, fileService), чтобы упростить и удовлетворить тест.

Выделите:

const sinon = require('sinon');
const { expect } = require('chai');
const LineByLinereader = require('line-by-line');

// Example class to show that real method not get called.
const notificationService = {
  validateNotification() {
    console.log('Real validateNotification get called');
    // Return the opposite value based on your test (true).
    return new Promise((r) => r(false));
  },
  createInAppNotification() {
    console.log('Real createInAppNotification get called');
    // Return the opposite value based on your test (true).
    return new Promise((r) => r(false));
  },
};

// Example class to show that real method not get called.
const fileService = {
  storeFile() {
    console.log('Real storeFile get called');
    // Return the opposite value based on your test (string not empty).
    return new Promise((r) => r(''));
  },
  deleteFile() {
    console.log('Real deleteFile get called');
    // Return the opposite value based on your test (true).
    return false;
  },
};

function getFile() {
  // Return real dummy file path.
  return {
    path: './test.txt',
  };
}

// Mocha asynchronous code using done.
it('POST /direct/bulk', (done) => {
  const file = getFile('notif-direct-bulk.csv');
  const stubValidateNotification = sinon.stub(notificationService, 'validateNotification');
  stubValidateNotification.resolves(true);
  const stubCreateInAppNotification = sinon.stub(notificationService, 'createInAppNotification');
  stubCreateInAppNotification.resolves(true);
  const stubStoreFile = sinon.stub(fileService, 'storeFile');
  stubStoreFile.resolves(file.path);
  const stubDeleteFile = sinon.stub(fileService, 'deleteFile');
  stubDeleteFile.returns(true);

  notificationService.validateNotification() // it's a stub
    .then(() => fileService.storeFile()) // it's a stub
    .then((storedFilePath) => {
      // Expect the result is correct with file above.
      expect(storedFilePath).to.equal(file.path);
      // Initiate synchronous processing of lines.
      const reader = new LineByLinereader(storedFilePath);
      console.log(notificationService.createInAppNotification()); // it's still a stub
      console.log(fileService.deleteFile()); // it's still a stub
      reader
        .on('line', async () => {
          // inside this scope the stubs are not working
          const result = await notificationService.createInAppNotification(); // calling the original method, not a stub
          expect(result).to.equal(true);
        })
        .on('end', () => {
          // inside this scope the stubs are not working
          const result = fileService.deleteFile(); // calling the original method, not a stub
          expect(result).to.equal(true);

          // Expect all stub get called once.
          expect(stubValidateNotification.calledOnce).to.equal(true);
          expect(stubCreateInAppNotification.calledOnce).to.equal(true);
          expect(stubStoreFile.calledOnce).to.equal(true);
          // You expect this stub to get called twice.
          expect(stubDeleteFile.calledTwice).to.equal(true);

          // Finish the test.
          done();
        });
    });
});

Когда я запускаю его, реальный метод не вызывается.

$ npx mocha stackoverflow.js


Promise { true }
true
  ✓ POST /direct/bulk

  1 passing (35ms)

$

Надеюсь, это поможет.

...