Шутка: как посчитать вызов из фиктивных методов, вызываемых через `call` или `apply`?

#javascript #unit-testing #mocking #jestjs

#javascript #модульное тестирование #издевательство #jestjs

Вопрос:

Как я могу использовать mocks для подсчета вызовов функций, выполняемых через call или apply

 // mylib.js
module.exports = {
  requestInfo: function(model, id) {
    return `The information for ${model} with ID ${id} is foobar`;
  },
  execute: function(name) {
    return this[name] amp;amp; this[name].apply(this, [].slice.call(arguments, 1));
  },
};
  
 // mylib.test.js
jest.mock('./mylib.js');

var myLib = require('./mylib.js');

test('', () => {
  myLib.execute('requestInfo', 'Ferrari', '14523');
  expect(myLib.execute.mock.calls.length).toBe(1); // Success!
  expect(myLib.requestInfo.mock.calls.length).toBe(1); // FAIL
});
  

Если я явно вызываю myLib.requestInfo , второе ожидание выполняется успешно.

Есть ли способ просмотреть фиктивные вызовы модулей, функции которых вызывались через apply или call ?

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

1. В вашем примере myLib нет arrangeViewing метода. Не могли бы вы, пожалуйста, обновить пример, иначе довольно сложно получить то, что вы пытаетесь.

2. Извините, я удалил неправильные методы из примера. Обновлено.

Ответ №1:

Из jest.mock документа:

Издевается над модулем с автоматически издевающейся версией, когда это требуется.

Документы, вероятно, можно было бы улучшить с помощью лучшего описания того, что означает «автоматически модифицируемая версия», но что происходит, так это то, что Jest поверхность API модуля остается неизменной, заменяя реализацию пустыми фиктивными функциями.


Итак, в этом случае execute вызывается, но она была заменена пустой фиктивной функцией, поэтому requestInfo никогда не вызывается, что приводит к сбою теста.


Чтобы сохранить execute реализацию неповрежденной, вы захотите избежать автоматической подделки всего модуля и вместо этого следить за исходной функцией с помощью чего-то вроде jest.spyOn :

 var myLib = require('./mylib.js');

test('', () => {
  jest.spyOn(myLib, 'execute');  // spy on execute
  jest.spyOn(myLib, 'requestInfo')  // spy on requestInfo...
    .mockImplementation(() => {});  // ...and optionally replace the implementation
  myLib.execute('requestInfo', 'Ferrari', '14523');
  expect(myLib.execute.mock.calls.length).toBe(1); // SUCCESS
  expect(myLib.requestInfo.mock.calls.length).toBe(1); // SUCCESS
});