如何使用jest和酶对使用继承而不是使用组合的反应组件进行单元测试?

时间:2018-05-08 08:13:44

标签: reactjs unit-testing redux react-router enzyme

我有一个扩展通用组件的组件(自定义反应组件)。如何使用酶的底座进行单元测试?这是代码:

Container.js

import React from 'react';
import request from 'API/request';

export default class Container extends React.Component {
  componentDidMount() {
    this.populateData();
  }

  componentDidUpdate() {
    if (this.isDataStale()) {
      return this.populateData();
    }
  }

  populateData() {
    const url = this.getUrl();
    const params = this.getParams();

return request(this.props.dispatch, {
  url,
  params,
  method: 'GET'
})
  .then(response => {
    this.dispatchData(response.data);
  })
  .catch(error => {
    this.dispatchError(error);
  });


}
render() {
    if (this.getData() && !this.isDataStale()) {
      return this.renderChildren();
    } else {
      return null;
    }
  }

  getError() {}
  getParams() {}
  isDataStale() {
    return false;
  }
}

这是功能组件:

import React from 'react';
import { connect } from 'react-redux';
import { Route, withRouter } from 'react-router-dom';
import CustomPage from 'Client/customPage';
import Container from 'Client/container';
import TestPanel from 'Client/testPanel/TestPanel';
import Greeting from 'Client/greeting';
import Button from '../Button';

export class Test extends Container {
  constructor({ match }) {
    super();
    this.state = {
      match: match,
      id: match.params.id,
      location: ''
    };
  }

  isDataStale() {
    return (
      this.props.data.id !== this.props.match.params.id
    );
  }

  getData() {
    return this.props.data.values;
  }

  dispatchData(data) {
    this.props.dispatch({
      type: 'DATA_FOUND',
      data: data,
      id: this.state.id
    });
  }

  dispatchError(error) {
    this.props.dispatch({ type: 'CUSTOM_ERROR', data: error });
  }

  showDetails(url) {
    this.props.history.push(url);
  }

  renderChildren() {
    const match = this.state.match;
    const testUrl = `/test/values/${this.state.id}`;
    const verifyUrl = `${testUrl}/verify`;

    return (
      <div className="test-plan">
        <Route path={verifyUrl} render={() => (
          <Greeting show={true} />
        )} />
        <TestPanel
          data={this.props.data}
          id={this.props.match.params.id}
        />
        <Route exact path={testUrl} render={() => (
          <CustomPage id={this.state.id} />
        )} />
        <Route path={verifyUrl} render={() => (
          <div className="next-button" ><Button label = {' NEXT '} onButtonClick = { this.showDetails.bind(this, loanUrl) } /> </div>
        )} />
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    data: state.data
  };
};

export default withRouter(connect(mapStateToProps)(Test));

如何使用酶测试此测试(功能)组件?我不确定这个模拟是如何工作的,因为render方法在容器内部,而容器又在我们的功能组件中调用renderChildren方法。许多功能组件扩展了这个容器,因此我们现在无法将其更改为合成模式。

这是测试用例(不工作)

import jsdomWindow from '../../test.setup';
import React from 'react';
import {BrowserRouter} from 'react-router-dom';
import { Test } from 'Client/containers/test';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import Enzyme, {mount} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import sinon from 'sinon';
import * as api from 'API/request';
import { populateData, isDataStale } from '../../../../src/client/app/container';

Enzyme.configure({ adapter: new Adapter() });
const sandbox = sinon.sandbox.create();

describe('<Test />',() => {
  beforeEach(function() {
    sandbox.stub(api, 'default').returns(Promise.resolve({data: { saySomething: 'Yay Tests!'}}));
  });

  afterEach(function() {
    sandbox.restore();
  });
  const match = {
    params: {
      id: 100
    }
  };
  const testState = {
    data : {
      test: {
        id:'100',
        email:'someone@something.com',
        first_name:'John',
        home_phone:'325-555-6564',
        last_name:'Doe'
      }
    }
  };
  const wrapper = mount(
    <BrowserRouter>
      <Provider store={createStore(state => state, { data: testState.data })}>
        <Test data={testState.data} dispatch={ sinon.spy() }
          match={match} />
      </Provider>
    </BrowserRouter>
  );
  jest.mock('../../../../src/client/app/container', () => ({
    populateData: jest.fn(),
    isDataStale: jest.fn(),
    getError: jest.fn(),
    getParams: jest.fn(),

  }));

  it('should render', () => {
    console.log(wrapper.debug());
    populateData.mockReturnValueOnce({});
    isDataStale.mockReturnValueOnce(false);
    const greetingContainer = wrapper.find('.greeting-container').find('.quick-info').find('.quick-info-heading');
    expect(greetingContainer.text()).toContain('PROPER RESPONSE');
  });

  // it('should render greeting component by default', () => {
  //   expect(wrapper.find('div.greeting-container')).toBeDefined();
  //   expect(wrapper.find('div.info-container')).toBeDefined();
  //   expect(wrapper.find('div.next-button')).toBeDefined();
  // });

  // it('should not render greeting and next-button components on clicking next', () => {
  //   console.log(`Test**** ${JSON.stringify(wrapper.find('div.plan'))}`);
  // });
});

任何人都可以帮助我使用酶的mount方法进行单元测试。不想在这里使用浅,因为我必须测试嵌套组件的属性。

谢谢。

0 个答案:

没有答案