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

时间:2017-07-07 12:23:26

标签: 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;

现在进行单元测试:

1。 我想运行main(1)并测试它返回2并且未调用child()

2。 然后我想运行main(2)并且它返回的3child(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);
  });

});

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

2 个答案:

答案 0 :(得分:10)

好的,我已经明白了。诀窍是,将功能拆分为单独的文件。所以代码是(并在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;

提取了child.js文件:

// child.js

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

exports.child = child;

主要测试文件:

// 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);
  });

});

答案 1 :(得分:0)

在我的情况下,我对角度代码也有类似的疑问,所以我有一个方法,当更改表单中的字段时会调用该方法,并且此方法的唯一任务是触发其他一些方法。

代码提取:

handleConnectionToLegChange(value) {
if (!isNullOrUndefined(value)) {
  this.connectionsForm.controls.to.markAsDirty();
  this.connectionsForm.controls.to.updateValueAndValidity();
  this.connectionsForm.controls.from.markAsDirty();
  this.connectionsForm.controls.from.updateValueAndValidity();
  this.updateModalButtonStatus(this.connectionsSubject);
}}

所以为了测试它,我使用了这个测试用例。 (我只是监视了5种触发方法中的2种,但这对我来说已经足够了。)

测试摘要:

 it('should execute fn handleConnectionToLegChange and check method calls if value is not null', () => {
component.connectionsForm.controls.to.updateValueAndValidity = jest.fn();
component.updateModalButtonStatus = jest.fn();
component.handleConnectionToLegChange('a');
expect(component.connectionsForm.controls.to.updateValueAndValidity).toHaveBeenCalled();
expect(component.updateModalButtonStatus).toHaveBeenCalled(); });

对我来说很好。