【问题标题】:Not able to mock a constructor´s property: ReferenceError: EventSource is not defined (Jest, Enzyme)无法模拟构造函数的属性:ReferenceError: EventSource is not defined (Jest, Enzyme)
【发布时间】:2021-10-31 06:20:57
【问题描述】:

在我的测试文件中,我正在安装一个组件,其中一个嵌套组件给我带来了麻烦。这是组件:

class CacheHandler extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      isLatestVersion: false,
      refreshCacheAndReload: () => {
        if (caches) {
          caches.keys().then((names) => {
            names.forEach((name) => {
              caches.delete(name);
            })
          });
        }
        window.location.reload(true);
      }
    };
     // ...some other code
  }
   
  render() {
    const { loading, isLatestVersion, refreshCacheAndReload } = this.state;
    return this.props.children({ loading, isLatestVersion, refreshCacheAndReload });
  }
}

CacheHandler.propTypes = {
  children: PropTypes.func.isRequired
};

export default CacheHandler;

我不知道如何正确地模拟构造函数的 refreshCacheAndReload 属性,这让我头发灰白。如果它在模拟中不做任何事情是完全可以的,但它应该在安装过程中被发现。目前,当我运行测试时,我得到了因为那部分 ReferenceError: EventSource is not defined

这是我在测试中尝试但失败的方法(错误:“CacheHandler”是只读的。):

const fakeCacheHandler = jest.fn(() => ({
  constructor(props) {
    //super(props);
    this.state = {
      loading: false,
      isLatestVersion: false,
      refreshCacheAndReload: () => { }
  }},
  render() {
    const { loading, isLatestVersion, refreshCacheAndReload } = this.state;
    return this.props.children({ loading, isLatestVersion, refreshCacheAndReload });
  }
  
}))     
CacheHandler = fakeCacheHandler; 

我也尝试直接在测试中定义属性但没有成功:

Object.defineProperty(CacheHandler, 'CacheHandler', {
  value: jest.fn().mockImplementation(query => ({
    loading: false,
    isLatestVersion: false,
    refreshCacheAndReload: () => {}
  }))
})

我还尝试像这样在测试中模拟整个模块:

jest.mock('../../components/utilities/CacheHandler', function() {  
  return jest.fn().mockImplementation(() => {       
       return {           
        refreshCacheAndReload: () => {},
        render: () => {this.props.children({ loading:false, isLatestVersion:false, refreshCacheAndReload })},        
}})
});

但仍然没有成功。

jest.spyOn 也失败(无法窥探 refreshCacheAndReload 属性,因为它不是函数;改为未定义)

const fakeHandler = new CacheHandler();

const methodSpy = jest.spyOn(fakeHandler, "refreshCacheAndReload"); 
methodSpy.mockImplementation(() => {
  console.log('test!');
})

这就是测试本身现在的样子:

  it('renders MembersList', async () => {
    const Component = withMemory(AdminAppCore, ROUTE_ADMIN_MEMBERS);
    const result = mount(
      <MockProvider stores={{ memberStore, programStore }}>
        <Component />
      </MockProvider>
      
    );
    console.log(result.debug());
    await waitForState(result, state => state.loading === false);
    expect(result.find(MembersList).length).toBe(1);
    result.unmount();
  });

我试图像这样在测试中模拟子元素的构造函数,但是如果失败(TypeError:this.props.children is not a function):

it('renders MembersList', async () => {
    const Component = withMemory(AdminAppCore, ROUTE_ADMIN_MEMBERS);
      const mockrefreshCacheAndReload = jest.fn(() => ({}));
      const component = shallow(<CacheHandler/>);
      component.setState({refreshCacheAndReload: mockrefreshCacheAndReload}); 
    const result = mount(
      <MockProvider stores={{ memberStore, programStore }}>
        <Component />
      </MockProvider>      
    );
    console.log(result.debug());
    await waitForState(result, state => state.loading === false);
    expect(result.find(MembersList).length).toBe(1);
    result.unmount();
  });

所以我正在安装 AdminAppCore,而 AdminAppCore 内部是导致麻烦的嵌套组件。

谁能解释我如何模拟嵌套组件构造函数中的 refreshCacheAndReload 状态?

【问题讨论】:

  • 你试过使用 jest spy 吗?它类似于 const methodSpy = jest.spy(classInstance, "methodNameInString"); methodSpy.mockImplementation..
  • 是的,我做到了,但我收到错误 TypeError: jest.spy is not a function :( 我这样尝试过: const methodSpy = jest.spy(CacheHandler, "refreshCacheAndReload"); methodSpy. mockImplementation(() => { //***** 实现**** })
  • 对不起,该函数被称为 jest.spyOn 而不是 jest.spy 此外,您可能需要一个 CacheHandler 的实例而不是类本身才能使其工作。
  • 我可以在测试本身内创建实例吗?我试过了,但没有用。我总是收到错误无法监视 refreshCacheAndReload 属性,因为它不是函数;给定的未定义
  • 好的,所以问题是我们忽略了方法是状态的一部分这一事实。为了测试这个组件,你需要使用 jest/enzyme 加载这个组件,然后为 refreshCacheAndReload 创建一个模拟函数,然后将它附加到状态。有意义吗?

标签: javascript unit-testing jestjs enzyme


【解决方案1】:

由于我无法在 cmets 中发布此内容,所以请尝试一下。

const mockrefreshCacheAndReload = jest.fn(() => ({}));

it('tests the method', () => {
    const component = shallow(<CacheHandler/>);
    component.setState({refreshCacheAndReload: mockrefreshCacheAndReload})
})

【讨论】:

  • 感谢 Zurez 的意见。不幸的是,它不适用于我,因为我没有直接浅化 。它被渲染为我挂载的 AdminAppCore 组件的子组件。我在安装 AdminnAppCore 之前尝试了您的提示,但结果是 TypeError: this.props.children is not a function。我会将这个失败的试验添加到我的问题中
猜你喜欢
  • 2020-06-14
  • 2021-03-29
  • 2019-12-02
  • 1970-01-01
  • 2014-03-03
  • 2018-12-02
  • 2020-08-14
  • 2021-03-19
  • 2018-12-26
相关资源
最近更新 更多