簡體   English   中英

如何使用 Jest 測試是否使用定義的參數 ( toHaveBeenCalledWith ) 調用函數

[英]How to test if function was called with defined parameters ( toHaveBeenCalledWith ) with Jest

我想測試一下,是否在我的測試中調用了特定的函數並使用了正確的參數。 從 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)並且它返回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);
  });

});

我正在https://repl.it/languages/jest 中對此進行測試,因此非常感謝此 REPL 中的工作示例。

好的,我已經想通了。 訣竅是,將函數拆分為單獨的文件。 所以代碼是(並在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);
  });

});

在我的例子中,我對 angular 代碼有類似的疑問,所以我有一個方法,當表單中的字段更改時調用該方法,並且該方法的唯一任務是觸發其他一些方法。

代碼提取:

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

它對我來說很好。

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



});

被嘲笑:

// child.js
function child(ch) {
  console.log('some side effects happen in here', ch);
}

exports.child = child;

待測試:

// main.js
const { child } = require('./child');

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

  return a + 1;
}

exports.main = main;

測試 main.js

// main.test.js
jest.mock('./child');
const { main } = require('./main');

// This is the mocked version of "child"
const { child } = require('./child');

describe('main', () => {

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

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

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM