jestjs - TypeError:intlProvider.getChildContext 不是函数
问题描述
我在我的反应功能组件中使用 injectIntl 来实现本地化。我正在使用酶/玩笑进行单元测试。我复制了 intl-test-helper 文件,但出现错误:“TypeError: intlProvider.getChildContext is not a function”
我已经尝试过来自 stackflow 的其他建议: 1. 删除模拟文件 --- 我没有模拟文件 2. 使用 const { IntlProvider } = jest.requireActual("react-intl"); 强制它使用实际的,而不是模拟的——不工作。
反应组件是:WarningModal.jsx:
import { FormattedMessage, injectIntl } from "react-intl";
.......
const WarningModal = ({
.........
...props
}) => {
........
export default injectIntl(WarningModal);
intlTestHelper.js 文件是:
* Components using the react-intl module require access to the intl context.
* This is not available when mounting single components in Enzyme.
* These helper functions aim to address that and wrap a valid,
* English-locale intl context around them.
*/
import React from "react";
import { IntlProvider, intlShape } from "react-intl";
import { mount, shallow } from "enzyme"; // eslint-disable-line import/no-extraneous-dependencies
/** Create the IntlProvider to retrieve context for wrapping around. */
function createIntlContext(messages, locale) {
const { IntlProvider } = jest.requireActual("react-intl");
const intlProvider = new IntlProvider({ messages, locale }, {});
const { intl } = intlProvider.getChildContext();
return intl;
}
/** When using React-Intl `injectIntl` on components, props.intl is required. */
function nodeWithIntlProp(node, messages = {}, locale = "en") {
return React.cloneElement(node, {
intl: createIntlContext(messages, locale)
});
}
/**
* Create a shadow renderer that wraps a node with Intl provider context.
* @param {ReactComponent} node - Any React Component
* @param {Object} context
* @param {Object} messages - A map with keys (id) and messages (value)
* @param {string} locale - Locale string
*/
export function shallowWithIntl(
node,
{ context } = {},
messages = {},
locale = "en"
) {
return shallow(nodeWithIntlProp(node), {
context: Object.assign({}, context, {
intl: createIntlContext(messages, locale)
})
});
}
/**
* Mount the node with Intl provider context.
* @param {Component} node - Any React Component
* @param {Object} context
* @param {Object} messages - A map with keys (id) and messages (value)
* @param {string} locale - Locale string
*/
export function mountWithIntl(
node,
{ context, childContextTypes } = {},
messages = {},
locale = "en"
) {
return mount(nodeWithIntlProp(node), {
context: Object.assign({}, context, {
intl: createIntlContext(messages, locale)
}),
childContextTypes: Object.assign({}, { intl: intlShape }, childContextTypes)
});
}
这里我如何使用它来测试:
import React from "react";
import { _WM as WarningModal } from "../components/WarningModal";
// import { shallow } from "enzyme";
import { mountWithIntl } from "../utils/intlTestHelper.js";
describe("<WarningModal />", () => {
const props = {
discardChanges: jest.fn(),
saveChanges: jest.fn(),
closeWarningModal: jest.fn(),
intl: { formatMessage: jest.fn() }
};
it("should have heading", () => {
const wrapper = mountWithIntl(<WarningModal {...props} />);
expect(wrapper.find(".confirm-title")).toBeTruthy();
});
});
错误:
● <WarningModal /> › should have heading
TypeError: intlProvider.getChildContext is not a function
14 | const { IntlProvider } = jest.requireActual("react-intl");
15 | const intlProvider = new IntlProvider({ messages, locale }, {});
> 16 | const { intl } = intlProvider.getChildContext();
| ^
17 | return intl;
18 | }
19 |
at getChildContext (src/utils/intlTestHelper.js:16:33)
at createIntlContext (src/utils/intlTestHelper.js:23:11)
at nodeWithIntlProp (src/utils/intlTestHelper.js:60:16)
at Object.<anonymous> (src/tests/WarningModal.spec.js:29:21)
请照亮这个。谢谢你。
解决方案
React-Intl
已将IntlProvider.getChildContext
, 替换为createIntl
用于测试目的,同时将 V2 迁移到 V3。
我们已经删除了 IntlProvider.getChildContext 用于测试,现在您可以使用 createIntl 在 React 之外创建一个独立的 intl 对象并将其用于测试目的。有关更多详细信息,请参阅使用 React Intl 进行测试
这是链接
所以这个的工作代码是
要解决此错误,您必须创建自定义浅组件。就像
import { createIntl } from 'react-intl';
const LocalLanguage = {
french:{},
arabic:{},
english:{}
}
const lang = getCurrentLanguage('en', LocalLanguage);
const intl = createIntl({ locale: 'en', lang }, {});
export const shallowWithIntl = (node) => {
return shallow(nodeWithIntlProp(node), { context: { intl } });
}
如果这没有帮助,那么您可以在帮助文件中定义以下函数。
const messages = require('./Lang/en.json') // en.json
const defaultLocale = 'en'
const locale = defaultLocale
export const intl = (component) => {
return (
<IntlProvider
locale={locale}
messages={messages}
>
{React.cloneElement(component)}
</IntlProvider>
);
}
并在您的测试文件中使用它,如下所示
const wrapper = mount(intl(<MobileRechargeComponent />));