将react-intl对象注入已安装的酶组件中以进行测试

解决了!向下滚动以获取答案


在我们的组件测试中,我们需要它们能够访问react-intl上下文。问题在于,我们正在安装单个组件(带有Enzyme的组件mount())而没有它们的<IntlProvider

/>父包装。可以通过以下方式解决此问题:将提供程序包装在一起,然后rootIntlProvider实例指向实例,而不要指向CustomComponent

该测试与阵营-国际:enzyme文档仍然是空的。

class CustomComponent extends Component {

state = {

foo: 'bar'

}

render() {

return (

<div>

<FormattedMessage id="world.hello" defaultMessage="Hello World!" />

</div>

);

}

}


(酶+摩卡咖啡+柴)

// This is how we mount components normally with Enzyme

const wrapper = mount(

<CustomComponent

params={params}

/>

);

expect( wrapper.state('foo') ).to.equal('bar');

但是,由于我们的组件FormattedMessage用作react-intl库的一部分,因此在运行上述代码时会出现此错误:

Uncaught Invariant Violation: [React Intl] Could not find requiredintlobject. <IntlProvider> needs to exist in the component ancestry.


const wrapper = mount(

<IntlProvider locale="en">

<CustomComponent

params={params}

/>

</IntlProvider>

);

这提供CustomComponentintl它要求的上下文。但是,在尝试测试诸如此类的断言时:

expect( wrapper.state('foo') ).to.equal('bar');

引发以下异常:

AssertionError: expected undefined to equal ''

这当然是因为它试图读取IntlProvider而不是我们的状态CustomComponent


回答:

我尝试了以下无济于事:

const wrapper = mount(

<IntlProvider locale="en">

<CustomComponent

params={params}

/>

</IntlProvider>

);

// Below cases have all individually been tried to call `.state('foo')` on:

// expect( component.state('foo') ).to.equal('bar');

const component = wrapper.childAt(0);

> Error: ReactWrapper::state() can only be called on the root

const component = wrapper.children();

> Error: ReactWrapper::state() can only be called on the root

const component = wrapper.children();

component.root = component;

> TypeError: Cannot read property 'getInstance' of null


现在的问题是:

回答:

我创建了一个辅助功能来修补现有的酶mount()shallow()功能。现在,我们在所有使用React Intl组件的测试中都使用这些辅助方法。

您可以在这里找到要点:https://gist.github.com/mirague/c05f4da0d781a9b339b501f1d5d33c37


为了保持数据的可访问性,以下是简而言之的代码:

/**

* 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';

const messages = require('../locales/en'); // en.json

const intlProvider = new IntlProvider({ locale: 'en', messages }, {});

const { intl } = intlProvider.getChildContext();

/**

* When using React-Intl `injectIntl` on components, props.intl is required.

*/

function nodeWithIntlProp(node) {

return React.cloneElement(node, { intl });

}

export default {

shallowWithIntl(node) {

return shallow(nodeWithIntlProp(node), { context: { intl } });

},

mountWithIntl(node) {

return mount(nodeWithIntlProp(node), {

context: { intl },

childContextTypes: { intl: intlShape }

});

}

};

class CustomComponent extends Component {

state = {

foo: 'bar'

}

render() {

return (

<div>

<FormattedMessage id="world.hello" defaultMessage="Hello World!" />

</div>

);

}

}

import { mountWithIntl } from 'helpers/intl-test';

const wrapper = mountWithIntl(

<CustomComponent />

);

expect(wrapper.state('foo')).to.equal('bar'); // OK

expect(wrapper.text()).to.equal('Hello World!'); // OK

以上是 将react-intl对象注入已安装的酶组件中以进行测试 的全部内容, 来源链接: utcz.com/qa/414893.html

回到顶部