Next.jsdynamic()HOC组件并不是很容易测试。
dynamic()
require.resolveWeak is not a function
modules
kpbwa7wx1#
让我们假设我们有一个这样的组件(使用动态导入):
import dynamic from 'next/dynamic'; const ReactSelectNoSSR = dynamic(() => import('../components/select'), { loading: () => <Input />, ssr: false }); export default () => ( <> <Header /> <ReactSelectNoSSR /> <Footer /> </> );
Next.js提供的动态导入支持并没有公开在Jest环境中预加载动态导入组件的方法。然而,由于jest-next-dynamic,我们可以呈现完整的组件树,而不是加载占位符。您需要将babel-plugin-dynamic-import-node添加到.babelrc中,如下所示。
.babelrc
{ "plugins": ["babel-plugin-dynamic-import-node"] }
然后,您可以使用preloadAll()来呈现组件,而不是加载占位符。
preloadAll()
import preloadAll from 'jest-next-dynamic'; import ReactSelect from './select'; beforeAll(async () => { await preloadAll(); });
📝 Source
2nbm6dog2#
您可以将以下内容添加到Jest设置示例中:setupTests.ts
setupTests.ts
jest.mock('next/dynamic', () => () => { const DynamicComponent = () => null; DynamicComponent.displayName = 'LoadableComponent'; DynamicComponent.preload = jest.fn(); return DynamicComponent; });
ctehm74n3#
下面将加载所需的组件。您也可以使用类似的方法预先加载所有组件。
jest.mock('next/dynamic', () => ({ __esModule: true, default: (...props) => { const dynamicModule = jest.requireActual('next/dynamic'); const dynamicActualComp = dynamicModule.default; const RequiredComponent = dynamicActualComp(props[0]); RequiredComponent.preload ? RequiredComponent.preload() : RequiredComponent.render.preload(); return RequiredComponent; }, }));
hm2xizp94#
虽然这是一个很笨拙的解决方案,但我所做的只是通过提取导入路径并返回该导入来模拟next/dynamic:
next/dynamic
jest.mock('next/dynamic', () => ({ __esModule: true, default: (...props) => { const matchedPath = /(.)*(\'(.*)\')(.)*/.exec(props[0].toString()); if (matchedPath) return require(matchedPath[3]); else return () => <></>; }, }));
q0qdq0h25#
下面是一个简单的修复方法:
1.通过在__mocks__/next/dynamic.js Jest docs中创建一个模拟文件来模拟next/dynamic模块1.复制并粘贴以下代码:
__mocks__/next/dynamic.js
const dynamic = (func) => { const functionString = func.toString() const modulePath = functionString.match(/"(.*?)"/)[1] const namedExport = functionString.match(/mod\.(.+?(?=\)))/) const componentName = namedExport ? namedExport[1] : 'default' return require(modulePath)[componentName] } export default dynamic
1.上面的代码假定您使用default和named exports的dynamic()函数,如Next.js docs中所述。即:
default
named exports
// default const DynamicHeader = dynamic(() => import('../components/header') ) // named export const DynamicComponent = dynamic(() => import('../components/hello').then((mod) => mod.Hello) )
就是这样!现在动态导入应该可以在所有的测试套件中工作了:)
uemypmqf6#
如果您遇到的是Next8的第一个问题,您可以使用以下代码模拟动态导入:
jest.mock('next-server/dynamic', () => () => 'Dynamic');
有关参考,请参见:https://spectrum.chat/next-js/general/with-jest-and-dynamic-imports-broken~25905aad-901e-41d8-ab3e-9f97eeb51610?m=MTU1MzA5MTU2NjI0Nw==https://github.com/zeit/next.js/issues/6187#issuecomment-467134205
6条答案
按热度按时间kpbwa7wx1#
让我们假设我们有一个这样的组件(使用动态导入):
Next.js提供的动态导入支持并没有公开在Jest环境中预加载动态导入组件的方法。然而,由于jest-next-dynamic,我们可以呈现完整的组件树,而不是加载占位符。
您需要将babel-plugin-dynamic-import-node添加到
.babelrc
中,如下所示。然后,您可以使用
preloadAll()
来呈现组件,而不是加载占位符。📝 Source
2nbm6dog2#
您可以将以下内容添加到Jest设置示例中:
setupTests.ts
ctehm74n3#
下面将加载所需的组件。您也可以使用类似的方法预先加载所有组件。
hm2xizp94#
虽然这是一个很笨拙的解决方案,但我所做的只是通过提取导入路径并返回该导入来模拟
next/dynamic
:q0qdq0h25#
下面是一个简单的修复方法:
解决方案:
1.通过在
__mocks__/next/dynamic.js
Jest docs中创建一个模拟文件来模拟next/dynamic
模块1.复制并粘贴以下代码:
1.上面的代码假定您使用
default
和named exports
的dynamic()
函数,如Next.js docs中所述。即:就是这样!现在动态导入应该可以在所有的测试套件中工作了:)
uemypmqf6#
如果您遇到的是Next8的第一个问题,您可以使用以下代码模拟动态导入:
有关参考,请参见:
https://spectrum.chat/next-js/general/with-jest-and-dynamic-imports-broken~25905aad-901e-41d8-ab3e-9f97eeb51610?m=MTU1MzA5MTU2NjI0Nw==
https://github.com/zeit/next.js/issues/6187#issuecomment-467134205