如何使用Jest测试是否使用定义的参数(toHaveBeenCalledWith)调用函数

DHl*_*aty 16 javascript unit-testing jestjs

我想测试,如果在我的测试中调用了特定的函数并且使用了正确的参数.从JEST文档中我无法弄清楚,正确的方法是什么.

假设我有这样的事情:

// add.js

function child(ch) {
   const t = ch + 1;
   // no return value here. Function has some other "side effect"
}


function main(a) {
  if (a == 2) {
    child(a + 2);
  }

  return a + 1;
}

exports.main = main;
exports.child = child;
Run Code Online (Sandbox Code Playgroud)

现在进行单元测试:

我想运行main(1)并测试它返回2并且child()没有被调用.

2.然后我想跑main(2),并且它返回3并且child(4)被称为恰好一次.

我现在有这样的事情:

// add-spec.js
module = require('./add');

describe('main', () => {

  it('should add one and not call child Fn', () => {
    expect(module.main(1)).toBe(2);
    // TODO: child() was not called
  });

  it('should add one andcall child Fn', () => {

    expect(module.main(2)).toBe(3);
    // TODO: child() was called with param 4 exactly once
    // expect(module.child).toHaveBeenCalledWith(4);
  });

});
Run Code Online (Sandbox Code Playgroud)

我正在https://repl.it/languages/jest中对此进行测试,因此非常感谢此REPL中的一个工作示例.

DHl*_*aty 12

好的,我已经弄清楚了.诀窍是,将功能拆分为单独的文件.所以代码是(并在https://repl.it/languages/jest中工作):

// add.js
child = require('./child').child;

function main(a) {
  if (a == 2) {
    child(a + 2);
  }

  return a + 1;
}

exports.main = main;
Run Code Online (Sandbox Code Playgroud)

提取的child.js文件:

// child.js

function child(ch) {
   const t = ch + 1;
   // no return value here. Function has some other "side effect"
}

exports.child = child;
Run Code Online (Sandbox Code Playgroud)

主要测试文件:

// add-spec.js
main = require('./add').main;
child = require('./child').child;

child = jest.fn();

describe('main', () => {

  it('should add one and not call child Fn', () => {
    expect(main(1)).toBe(2);

    expect(child).toHaveBeenCalledTimes(0);
  });

  it('should add one andcall child Fn', () => {
    expect(main(2)).toBe(3);

    expect(child).toHaveBeenCalledWith(4);
    expect(child).toHaveBeenCalledTimes(1);
  });

});
Run Code Online (Sandbox Code Playgroud)

  • 如果你打算用 `jest.fn()` 覆盖 `child`,那么你可能不需要 child,对吗? (4认同)
  • @DHlavaty,诀窍是使用`child = jest.fn();`,而不是将函数拆分成单独的文件,对吗? (2认同)

Art*_*Ali 5

let child = require('./child');
let main = require('./add').main;

// name of the module, name of the function
spy = jest.spyOn(child, 'child');

describe('main', () => {

  it('should add one and call child Fn', () => {
    expect(main(1)).toBe(2);
    // Called or not
    expect(spy).toHaveBeenCalled();
  });



});
Run Code Online (Sandbox Code Playgroud)