Шутка: как посчитать вызов из ложных методов, вызываемых через `call` или` apply`? - PullRequest
0 голосов
/ 03 марта 2019

Как я могу использовать 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] && 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 Ответ

0 голосов
/ 04 марта 2019

Из jest.mock doc :

Проверяет модуль с автоматически смоделированной версией, когда это требуется.

Документы, вероятно, можно было бы улучшить с помощью лучшего описания того, что означает «автоматически смоделированная версия», но происходит то, что 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
});
...