【问题标题】:jest mocking and setting up default behavior开玩笑模拟和设置默认行为
【发布时间】:2020-05-29 13:37:44
【问题描述】:

我需要对一个函数进行单元测试:

const readiness = require("./readiness");

function stopProcessNewRequests(){
    readiness.setNotReady();
}

这是我的“准备就绪”文件:

const state = require("./state");
const hooks = require("./hooks");

function setReady(){
    state.ready = true;
    hooks.notifyHook(state.ready);
}

function setNotReady(){
    state.ready = false;
    hooks.notifyHook(state.ready);
}

module.exports = {
    setReady, setNotReady
};

最后是 state.js 文件:


exports.ready = false;

exports.pendingRequests = {};

exports.changeStatusHooks = [];

exports.requestsInProcessNum = 0;

exports.authClient = null;
exports.webOperationsClient = null;
exports.webQueryClient = null;

如您所见,有多个链式导入,我如何模拟它们?我需要我的状态文件具有某些值,以便检查它是否真的发生了变化。 这是我所拥有的,但 state 似乎没有改变,并且测试失败了。

describe('Testing processing new requests:', ()=> {
        test('should stop processing new requests:', ()=> {
            // jest.mock('../lib/grpc/readiness',);
            jest.mock('../lib/grpc/state');

            const state = require("../lib/grpc/state");
            const { stopProcessNewRequests } = require('../lib/grpc/requestsManager');

            state.ready = true;

            stopProcessNewRequests();

            expect(state.ready).toBeFalsy();
        })
    })

【问题讨论】:

  • 问题是准备文件导入状态,并且在测试时改变了原始文件,而不是我在测试中需要的那个。

标签: javascript node.js unit-testing testing jestjs


【解决方案1】:

最好不要跨模块进行测试。这意味着要测试requestsManager 模块,您应该模拟readiness 模块,而不是间接模拟模块statehooks。另外jest.mock应该用在函数范围内,应该用在模块范围内。

例如

readiness.js:

const state = require('./state');
const hooks = require('./hooks');

function setReady() {
  state.ready = true;
  hooks.notifyHook(state.ready);
}

function setNotReady() {
  state.ready = false;
  hooks.notifyHook(state.ready);
}

module.exports = {
  setReady,
  setNotReady,
};

hooks.js:

function notifyHook() {}

module.exports = { notifyHook };

requestsManager.js:

const readiness = require('./readiness');

function stopProcessNewRequests() {
  readiness.setNotReady();
}

module.exports = { stopProcessNewRequests };

state.js:

exports.ready = false;

exports.pendingRequests = {};

exports.changeStatusHooks = [];

exports.requestsInProcessNum = 0;

exports.authClient = null;
exports.webOperationsClient = null;
exports.webQueryClient = null;

以下是测试文件:

requestsManager.test.js:

const { stopProcessNewRequests } = require('./requestsManager');
const readiness = require('./readiness');

describe('62057531', () => {
  it('should pass', () => {
    const setNotReadyMock = jest.spyOn(readiness, 'setNotReady').mockReturnValueOnce();
    stopProcessNewRequests();
    expect(setNotReadyMock).toBeCalledTimes(1);
  });
});

readiness.test.js:

const { setNotReady, setReady } = require('./readiness');
const hooks = require('./hooks');
const state = require('./state');

describe('62057531', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  it('should set state to not ready', () => {
    jest.spyOn(hooks, 'notifyHook').mockReturnValueOnce();
    setNotReady();
    expect(hooks.notifyHook).toBeCalledWith(false);
    expect(state.ready).toBeFalsy();
  });

  it('should set state to ready', () => {
    jest.spyOn(hooks, 'notifyHook').mockReturnValueOnce();
    setReady();
    expect(hooks.notifyHook).toBeCalledWith(true);
    expect(state.ready).toBeTruthy();
  });
});

带有覆盖率报告的单元测试结果:

 PASS  stackoverflow/62057531/requestsManager.test.js (14.294s)
  62057531
    ✓ should pass (6ms)

 PASS  stackoverflow/62057531/readiness.test.js
  62057531
    ✓ should set state to not ready (5ms)
    ✓ should set state to ready (1ms)

--------------------|---------|----------|---------|---------|-------------------
File                | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
--------------------|---------|----------|---------|---------|-------------------
All files           |     100 |      100 |      75 |     100 |                   
 hooks.js           |     100 |      100 |       0 |     100 |                   
 readiness.js       |     100 |      100 |     100 |     100 |                   
 requestsManager.js |     100 |      100 |     100 |     100 |                   
 state.js           |     100 |      100 |     100 |     100 |                   
--------------------|---------|----------|---------|---------|-------------------
Test Suites: 2 passed, 2 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        17.288s, estimated 21s

【讨论】:

    猜你喜欢
    • 2018-04-13
    • 2019-09-25
    • 2018-07-25
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    相关资源
    最近更新 更多