本文介绍了Jest 模拟内部函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 helper.js 的文件,它包含两个函数

I have one file called helper.js that consist of two functions

export const funcA = (key) => {
   return funcB(key)
};

export const funcB = (key,prop) => {
   return someObj;
};

我有我的 helper.spec.js 来测试 helper.js 文件功能.

I have my helper.spec.js to test the helper.js file functions.

import {funcA,funcB} from 'helper';

describe('helper', () => {
   test('testFuncB', () => {

   }
   test('testFuncA', () => {

   }
}

funcB 的测试非常简单,我只是调用它并期望 someObj
问题是测试funcA,为了测试它我想模拟funcB的响应.

The test for funcB is pretty simple i just call it and expect someObj
The problem is to test funcA, in order to test it i want to mock the response of funcB.

我想要 testFuncB 调用实际的 funcBtestFuncA 调用模拟的 funcB

I want testFuncB call the actual funcB and testFuncA call mocked funcB

如何在我的两个测试中实现 funcB 的模拟和原创?

How can i achieve funcB to be mocked and original in my two tests?

这不是重复的.这是一个不同的情况:他们只模拟内部调用的函数,如果我删除 testFuncB 那么它会是一样的,但我也必须对 testFuncB 执行测试.

This is not a duplicate. It is a different case: they mock inner called functions only, if I remove the testFuncB then it will be the same but I must perform test on testFuncB too.

推荐答案

如果一个 ES6 模块直接导出两个函数(不在类、对象等内,直接导出问题中的函数)并且一个直接调用另一个,那么 该调用不能被模拟强>.

If an ES6 module directly exports two functions (not within a class, object, etc., just directly exports the functions like in the question) and one directly calls the other, then that call cannot be mocked.

在这种情况下,funcB 不能在 funcA 内模拟代码当前编写的方式.

In this case, funcB cannot be mocked within funcA the way the code is currently written.

模拟替换了 funcBmodule export,但是 funcA 不调用 module exportfuncB,它只是直接调用funcB.

A mock replaces the module export for funcB, but funcA doesn't call the module export for funcB, it just calls funcB directly.

funcA 中模拟funcB 要求funcAfuncB 调用模块导出>.

Mocking funcB within funcA requires that funcA call the module export for funcB.

这可以通过以下两种方式之一完成:

That can be done in one of two ways:

移动 funcB 到它自己的模块

Move funcB to its own module

funcB.js

export const funcB = () => {
  return 'original';
};

helper.js

import { funcB } from './funcB';

export const funcA = () => {
  return funcB();
};

helper.spec.js

helper.spec.js

import * as funcBModule from './funcB';
import { funcA } from './helper';

describe('helper', () => {

  test('test funcB', () => {
    expect(funcBModule.funcB()).toBe('original');  // Success!
  });

  test('test funcA', () => {
    const spy = jest.spyOn(funcBModule, 'funcB');
    spy.mockReturnValue('mocked');

    expect(funcA()).toBe('mocked');  // Success!

    spy.mockRestore();
  });
});

将模块导入自身

"ES6 模块自动支持循环依赖" 所以它是完全有效的import一个模块到自身中,这样模块内的函数就可以为模块中的其他函数调用模块导出:

"ES6 modules support cyclic dependencies automatically" so it is perfectly valid to import a module into itself so that functions within the module can call the module export for other functions in the module:

helper.js

import * as helper from './helper';

export const funcA = () => {
  return helper.funcB();
};

export const funcB = () => {
  return 'original';
};

helper.spec.js

helper.spec.js

import * as helper from './helper';

describe('helper', () => {

  test('test funcB', () => {
    expect(helper.funcB()).toBe('original');  // Success!
  });

  test('test funcA', () => {
    const spy = jest.spyOn(helper, 'funcB');
    spy.mockReturnValue('mocked');

    expect(helper.funcA()).toBe('mocked');  // Success!

    spy.mockRestore();
  });
});

这篇关于Jest 模拟内部函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-10 11:24