这是我的懒惰组件:
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>
)
在我的测试中,我有这种东西:
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);
})
})
我希望测试能够通过,console.log打印出来:
<Suspense fallback={{...}}>
<Bones />
</Suspense>
但是我得到<Bones />
而不是<lazy />
,但它未通过测试。
如何模拟导入的Lazy React组件,以使我的简单测试通过?
答案 0 :(得分:3)
我不确定这是否是您要寻找的答案,但这听起来像是问题的一部分nominal_features
。根据{{3}},transform_df
无法与shallow
一起使用。
但是,shallow
在尝试对惰性组件存根时也不起作用-如果您调试DOM输出(使用React.lazy
),则可以看到mount
在DOM中,但它是真实的(非存根)版本。
好消息:如果您只想检查console.log(wrapper.debug())
是否存在,则根本不必模拟该组件!该测试通过:
Bones
如果由于其他原因需要模拟组件,Bones
将允许您这样做,但这听起来像是您在尝试避免使用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();
});
});
。 this thread在jest
的上下文中讨论了其他一些选项(例如
This thread),也可以与jest
一起使用。
答案 1 :(得分:1)
您不需要使用lazy()
来解析.then(x => x.default)
函数,React已经为您完成了。
React.lazy采用必须调用动态import()的函数。这必须返回一个Promise,该Promise解析为一个带有默认导出的模块,该模块包含一个React组件。 React code splitting
语法应类似于:
const LazyBones = React.lazy(() => import("./LazyBones"))
示例:
// LazyComponent.js
import React from 'react'
export default () => (
<div>
<h1>I'm Lazy</h1>
<p>This component is Lazy</p>
</div>
)
// App.js
import React, { lazy, Suspense } from 'react'
// This will import && resolve LazyComponent.js that located in same path
const LazyComponent = lazy(() => import('./LazyComponent'))
// The lazy component should be rendered inside a Suspense component
function App() {
return (
<div className="App">
<Suspense fallback={<p>Loading...</p>}>
<LazyComponent />
</Suspense>
</div>
)
}
关于测试,您可以按照create-react-app
中默认提供的React测试示例进行更改,并对其进行一些更改。
创建一个名为LazyComponent.test.js
的新文件并添加:
// LazyComponent.test.js
import React, { lazy, Suspense } from 'react'
import { render, screen } from '@testing-library/react'
const LazyComponent = lazy(() => import('./LazyComponent'))
test('renders lazy component', async () => {
// Will render the lazy component
render(
<Suspense fallback={<p>Loading...</p>}>
<LazyComponent />
</Suspense>
)
// Match text inside it
const textToMatch = await screen.findByText(/I'm Lazy/i)
expect(textToMatch).toBeInTheDocument()
})
实时示例:点击浏览器标签旁边的测试标签。如果它不起作用,只需重新加载页面即可。
您可以在其react-testing-library网站上找到更多Docs复杂的示例。
答案 2 :(得分:-2)
要模拟您的惰性组件,首先想到的是将测试转换为异步并等待组件存在,例如:
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();
}