首页 > 解决方案 > 如何监视组件外部的功能?

问题描述

// ./index.js
import { Component } from 'react';

export default class Test extends Component {
    method () {
        console.log('method()');
    }

    do () {
        this.method();
        func();
    }

    render () {
        return null;
    }
}

export function func () {
    console.log('func()');
}

// ./index.test.js
import { shallow } from 'enzyme';
import React from 'react';
import * as Test from './index';

describe('<Test>', () => {
    const component = shallow(<Test.default/>),
          method_spy = jest.spyOn(component.instance(), 'method'),
          func_spy = jest.spyOn(Test, 'func');

    test('func()', () => {
        component.instance().do();
        expect(method_spy).toHaveBeenCalledTimes(1); // passed
        expect(func_spy).toHaveBeenCalledTimes(1); // failed
    });
});

我想监视组件外部的功能,但效果不佳。

我有一条消息Expected mock function to have been called one time, but it was called zero times.

而且我不想在这种情况下使用 mock() 方法而不是 spyOn() 。

有办法解决吗?谢谢你的阅读。:D

标签: jestjsenzyme

解决方案


它不起作用,因为这一行:

const func_spy = jest.spyOn(Test, 'func');

...正在为...的模块导出创建一个间谍func

...但Test.do不调用模块导出funcfunc直接调用。


有两个选项可以修复它。

一种是移动func到它自己的模块中。

然后它的模块导出将被导入index.js并在其中调用Test.do...

...并且当模块导出func包装在间谍中时,间谍将被Test.do.


另一种选择是注意“ES6 模块自动支持循环依赖”,因此可以将模块导入自身。

如果模块被导入自身,则可以Test.do调用模块导出func

import { Component } from 'react';
import * as index from './index';  // <= import the module into itself

export default class Test extends Component {
  method() {
    console.log('method()');
  }

  do() {
    this.method();
    index.func();  // <= use the module
  }

  render() {
    return null;
  }
}

export function func() {
  console.log('func()');
}

...并且模块导出的间谍func将按预期调用:

import { shallow } from 'enzyme';
import React from 'react';
import * as Test from './index';

describe('<Test>', () => {
  const component = shallow(<Test.default />),
    method_spy = jest.spyOn(component.instance(), 'method'),
    func_spy = jest.spyOn(Test, 'func');

  test('func()', () => {
    component.instance().do();
    expect(method_spy).toHaveBeenCalledTimes(1);  // Success!
    expect(func_spy).toHaveBeenCalledTimes(1);  // Success!
  });
});

推荐阅读