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

问题描述

我有一个名为 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 呼叫实际的 funcB testFuncA 嘲笑的 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.

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

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

模拟代替了funcB的模块导出,但funcA并未调用funcB的模块导出,它只是调用了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要求funcA调用>的模块导出.

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

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

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

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

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

09-09 13:19