Javascript 模拟导入的惰性反应组件

Javascript 模拟导入的惰性反应组件,javascript,reactjs,sinon,javascript-import,react-suspense,Javascript,Reactjs,Sinon,Javascript Import,React Suspense,下面是我的惰性组件: const LazyBones = React.lazy(() => import('@graveyard/Bones') .then(module => ({default: module.BonesComponent})) export default LazyBones 我是这样导入的: import Bones from './LazyBones' export default () => ( <Suspense fallback={

下面是我的惰性组件:

const LazyBones = React.lazy(() => import('@graveyard/Bones')
  .then(module => ({default: module.BonesComponent}))
export default LazyBones
我是这样导入的:

import Bones from './LazyBones'

export default () => (
<Suspense fallback={<p>Loading bones</p>}>
  <Bones />
</Suspense>
)
从“./LazyBones”导入骨骼
导出默认值()=>(
)
在我的测试中,我有这样的东西:

import * as LazyBones from './LazyBones';

describe('<BoneYard />', function() {
  let Bones;
  let wrapper;
  beforeEach(function() {
    Bones = sinon.stub(LazyBones, 'default');
    Bones.returns(() => (<div />));
    wrapper = shallow(<BoneYard />);
  });
  afterEach(function() {
    Bones.restore();
  });

  it('renders bones', function() {
    console.log(wrapper)
    expect(wrapper.exists(Bones)).to.equal(true);
  })

})
import*作为“/LazyBones”中的懒汉;
描述(“”,函数(){
让骨头;
让包装纸;
beforeach(函数(){
Bones=sinon.stub(LazyBones,'default');
返回(()=>());
包装器=浅();
});
之后(函数(){
恢复骨骼();
});
它('渲染骨骼',函数(){
日志(包装器)
expect(wrapper.exists(Bones)).to.equal(true);
})
})
我希望通过测试,并打印console.log:

<Suspense fallback={{...}}>
  <Bones />
</Suspense>

但是我得到的不是
,而是
,它没有通过测试


如何模拟导入的Lazy-React组件,以便通过简单的测试?

您不需要使用
解析
Lazy()
函数。然后(x=>x.default)
React已经为您解决了这个问题

React.lazy接受一个必须调用动态导入()的函数。这必须返回一个承诺,该承诺解析为具有包含React组件的默认导出的模块

语法应该类似于:

const LazyBones=React.lazy(()=>import(“./LazyBones”))
示例:

//LazyComponent.js
从“React”导入React
导出默认值()=>(
我很懒
这个组件是惰性的

) //App.js 从“React”导入React,{lazy,suspent} //这将导入并解析位于同一路径中的LazyComponent.js 常量LazyComponent=lazy(()=>import('./LazyComponent')) //惰性组件应该在悬念组件中呈现 函数App(){ 返回( ) }


至于测试,您可以按照
create React app
中默认提供的React测试示例进行操作,并对其进行一些更改

创建一个名为
LazyComponent.test.js的新文件,并添加:

//LazyComponent.test.js
从“React”导入React,{lazy,suspent}
从'@testing library/react'导入{render,screen}
常量LazyComponent=lazy(()=>import('./LazyComponent'))
测试('renders lazy component',async()=>{
//将呈现惰性组件
渲染(
)
//匹配其中的文本
const textToMatch=wait screen.findByText(/I'm Lazy/I)
expect(textToMatch).toBeInTheDocument()
})
实时示例:单击浏览器选项卡旁边的测试选项卡。如果不起作用,只需重新加载页面


您可以在他们的网站上找到更复杂的示例。

要模拟您的懒惰组件,首先考虑的是将测试转换为异步,并等待组件存在,如:

import CustomComponent, { Bones } from './Components';

it('renders bones', async () => {
   const wrapper = mount(<Suspense fallback={<p>Loading...</p>}>
                       <CustomComponent />
                   </Suspense>

   await Bones;
   expect(wrapper.exists(Bones)).toBeTruthy();
}
import CustomComponent,{Bones}来自“/Components”;
它('呈现骨骼',异步()=>{
常量包装器=装入(
等待骨头;
expect(wrapper.exists(Bones)).toBeTruthy();
}

我不确定这是否是您要寻找的答案,但听起来问题的一部分是
。根据,
不适用于
反应。懒惰

但是,
mount
在尝试存根惰性组件时也不起作用-如果您调试DOM输出(使用
console.log(wrapper.debug())
),您可以看到
Bones
在DOM中,但它是真实的(未存根的)版本

好消息是:如果您只是尝试检查
骨骼是否存在,则根本不必模拟组件!此测试通过:

import { Bones } from "./Bones";
import BoneYard from "./app";

describe("<BoneYard />", function() {
  it("renders bones", function() {
    const wrapper = mount(<BoneYard />);
    console.log(wrapper.debug());
    expect(wrapper.exists(Bones)).to.equal(true);
    wrapper.unmount();
  });
});
从“/Bones”导入{Bones};
从“/app”导入骨灰场;
描述(“,函数(){
它(“渲染骨骼”,函数(){
const wrapper=mount();
log(wrapper.debug());
expect(wrapper.exists(Bones)).to.equal(true);
wrapper.unmount();
});
});
如果您确实需要出于不同的原因模拟组件,
jest
将允许您这样做,但听起来您似乎在试图避免
jest
。在
jest
的上下文中讨论一些其他选项(例如。
)这可能也适用于
sinon

使用sinon不可能吗?我不想说服我的团队改变1000多个测试,这样我就可以涵盖一件事。当然可能,这些例子只是为了得到想法,你可以遵循同样的原则,做更复杂的事情。也许会有点帮助。我看了一下,找不到答案sinon中的等效项。因此“使用不同的测试库”是没有用的。@Pureferret您可以直接使用jest.spyOn来监视对象的行为,如jest.spyOn(props,'onChange')。否则,请记住jest.fn()返回的对象具有类似sinon的属性。@xargr我没有使用jest(很遗憾)。这个答案并不涉及玩笑。我不知道你为什么要提出这个问题?这对我安装的组件的结果没有影响。不幸的是,真正的bones组件必须是存根的,因为它包含一个es6导入。但这对其他人来说是一个很好的答案。