开玩笑的模拟内部功能

Ale*_*lik 12 javascript jestjs

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

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

export const funcB = (key,prop) => {
   return someObj;
};
Run Code Online (Sandbox Code Playgroud)

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

import {funcA,funcB} from 'helper';

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

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

   }
}
Run Code Online (Sandbox Code Playgroud)

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

我希望testFuncB调用实际的funcB,testFuncA调用模拟的funcB

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

这不是重复项。这是不同的情况:它们仅模拟内部调用的函数,如果我删除了testFuncB,那将是相同的,但是我也必须对testFuncB进行测试。

Bri*_*ams 14

如果ES6模块直接导出两个函数(不在类,对象等内部,而是直接导出问题中的函数),而一个直接调用另一个函数,则无法模拟该调用

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

有模拟替换模块出口funcB,但funcA不调用模块输出funcB,它只是调用funcB直接。


惩戒funcBfuncA需要funcA调用模块出口funcB

可以通过以下两种方式之一完成此操作:


移至funcB自己的模块

funcB.js

export const funcB = () => {
  return 'original';
};
Run Code Online (Sandbox Code Playgroud)

helper.js

import { funcB } from './funcB';

export const funcA = () => {
  return funcB();
};
Run Code Online (Sandbox Code Playgroud)

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();
  });
});
Run Code Online (Sandbox Code Playgroud)

将模块导入自身

“ ES6模块自动支持循环依赖关系”,因此对于import将模块本身嵌入模块是完全有效的,以便模块中的功能可以为模块中的其他功能调用模块导出

helper.js

import * as helper from './helper';

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

export const funcB = () => {
  return 'original';
};
Run Code Online (Sandbox Code Playgroud)

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();
  });
});
Run Code Online (Sandbox Code Playgroud)


Mat*_*Vio 8

迟到的答案但这应该有效。另外,您应该在自己的文件中测试 funcB,而不是在“帮助程序”测试中。

import { funcB } from './funcB';
import { funcA } from './helper';

jest.mock('./funcB');

describe('helper', () => {
    test('test funcA', () => {
        const funcBSpy = jest.fn();
        funcB.mockImplementation(() => funcBSpy());
        
        funcA();

        expect(funcBSpy).toHaveBeenCalledTimes(1);
    });
});
Run Code Online (Sandbox Code Playgroud)