首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将反应物注入装入酶组分进行测试

将反应物注入装入酶组分进行测试
EN

Stack Overflow用户
提问于 2016-05-04 07:31:24
回答 1查看 16.3K关注 0票数 24

编辑:解决了!向下滚动寻找答案

在我们的组件测试中,我们需要它们能够访问react-intl上下文。问题是,我们正在安装单个组件(用酶的mount()),而不使用它们的<IntlProvider />父包装。这可以通过包装提供者来解决,但是root指向IntlProvider实例,而不是CustomComponent

反应试验.Intl:酶文档仍然是空的。

代码语言:javascript
运行
复制
class CustomComponent extends Component {
  state = {
    foo: 'bar'
  }

  render() {
    return (
      <div>
        <FormattedMessage id="world.hello" defaultMessage="Hello World!" />
      </div>
    );
  }
}

标准测试用例(所需)(酶+ Mocha + Chai)

代码语言:javascript
运行
复制
// 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 required `intl` object. <IntlProvider> needs to exist in the component ancestry.

IntlProvider包装的

代码语言:javascript
运行
复制
const wrapper = mount(
  <IntlProvider locale="en">
    <CustomComponent
      params={params}
    />
  </IntlProvider>
);

这为CustomComponent提供了它所要求的intl上下文。但是,在尝试执行这样的测试断言时:

代码语言:javascript
运行
复制
expect( wrapper.state('foo') ).to.equal('bar');

引发以下异常:

AssertionError: expected undefined to equal ''

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

访问CustomComponent的尝试

我尝试了以下几点,但没有结果:

代码语言:javascript
运行
复制
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

问题是:如何在仍然能够在我们的CustomComponent CustomComponent上执行“根”操作的同时,用 intl 上下文安装?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-04 09:03:27

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

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

为了保持数据的可访问性,下面是一个简单的代码:

helpers/intl-test.js

代码语言:javascript
运行
复制
/**
 * 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 }
    });
  }
};

CustomComponent

代码语言:javascript
运行
复制
class CustomComponent extends Component {
  state = {
    foo: 'bar'
  }

  render() {
    return (
      <div>
        <FormattedMessage id="world.hello" defaultMessage="Hello World!" />
      </div>
    );
  }
}

CustomComponentTest.js

代码语言:javascript
运行
复制
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
票数 27
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37021217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档