编程语言
首页 > 编程语言> > javascript – 如何使用jest在同一模块中模拟函数

javascript – 如何使用jest在同一模块中模拟函数

作者:互联网

正确模拟以下示例的最佳方法是什么?

问题是在导入时间之后,foo会保留对原始未模拟条形的引用.

module.js:

export function bar () {
    return 'bar';
}

export function foo () {
    return `I am foo. bar is ${bar()}`;
}

module.test.js:

import * as module from '../src/module';

describe('module', () => {
    let barSpy;

    beforeEach(() => {
        barSpy = jest.spyOn(
            module,
            'bar'
        ).mockImplementation(jest.fn());
    });


    afterEach(() => {
        barSpy.mockRestore();
    });

    it('foo', () => {
        console.log(jest.isMockFunction(module.bar)); // outputs true

        module.bar.mockReturnValue('fake bar');

        console.log(module.bar()); // outputs 'fake bar';

        expect(module.foo()).toEqual('I am foo. bar is fake bar');
        /**
         * does not work! we get the following:
         *
         *  Expected value to equal:
         *    "I am foo. bar is fake bar"
         *  Received:
         *    "I am foo. bar is bar"
         */
    });
});

谢谢!

编辑:我可以改变:

export function foo () {
    return `I am foo. bar is ${bar()}`;
}

export function foo () {
    return `I am foo. bar is ${exports.bar()}`;
}

但这是p.在我看来,到处都是丑陋的:/

解决方法:

问题似乎与您期望如何解决bar的范围有关.

一方面,在module.js中导出两个函数(而不是一个包含这两个函数的对象).由于模块的导出方式,对导出的东西的容器的引用就像你提到的那样是导出.

另一方面,您处理导出(您使用别名模块)就像一个持有这些函数的对象并尝试替换其中一个函数(函数栏).

如果仔细观察你的foo实现,你实际上是对bar函数有一个固定的引用.

当您认为用新的替换了bar函数时,您实际上已经替换了module.test.js范围内的参考副本

为了让foo实际使用另一个版本的bar,你有两种可能:

>在module.js中导出一个类或一个实例,同时保存foo和bar方法:

Module.js:

export class MyModule {
  function bar () {
    return 'bar';
  }

  function foo () {
    return `I am foo. bar is ${this.bar()}`;
  }
}

请注意在foo方法中使用此关键字.

Module.test.js:

import { MyModule } from '../src/module'

describe('MyModule', () => {
  //System under test :
  const sut:MyModule = new MyModule();

  let barSpy;

  beforeEach(() => {
      barSpy = jest.spyOn(
          sut,
          'bar'
      ).mockImplementation(jest.fn());
  });


  afterEach(() => {
      barSpy.mockRestore();
  });

  it('foo', () => {
      sut.bar.mockReturnValue('fake bar');
      expect(sut.foo()).toEqual('I am foo. bar is fake bar');
  });
});

>就像你说的那样,重写全局出口容器中的全局引用.这不是推荐的方法,因为如果没有正确地将导出重置为其初始状态,您可能会在其他测试中引入奇怪的行为.

标签:javascript,mocking,testing,jestjs
来源: https://codeday.me/bug/20190930/1834743.html