sepulka
sepulka

Reputation: 405

Enzyme: shallow render inner react-redux components

I have simple react component, that use Card from antd:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Card } from 'antd';

export class TBD extends Component {

  constructor() {
    super();
  }

  render() {
    return (
      <Card title={this.props.pathname}>
        TODO
      </Card>
    );
  }
}

export let select = (state) => {
  return state.route;
};

export default connect(select)(TBD);

Now I write some simple test and want to check, that my TBD component use Card

import React from 'react';
import {mount, shallow}  from 'enzyme';
import {Provider, connect}  from 'react-redux';
import {createMockStore}  from 'redux-test-utils';
import {expect} from 'chai';
import chai from 'chai';
import chaiEnzyme from 'chai-enzyme';
chai.use(chaiEnzyme());
import { Card } from 'antd';
import TBDConnected,  {TBD, select} from '../src/js/components/TBD';

describe('Fully Connected:', function () {
    it('show selected item text', function () {

      const expectedState = {route: {pathname: 'Menu1'}};
      const store = createMockStore(expectedState);
      const ConnectedComponent = connect(select)(TBDConnected);
      const component = shallow(<ConnectedComponent store={store} />).shallow().shallow();
      console.log(component.debug());
      expect(component.equals(<Card/>)).is.equal(true);
    });
  });

And it fail, because 3 shallow return me

<Component title="Menu1">
TODO
</Component>

But I'm expect

<Card title="Menu1">
TODO
</Card>

After one more render I get pure html from rendering Card I'm not understand why it render it to Component instead Card and how I can get result what I want.

Update

Example that simplifier my question. Next test fail:

describe('TBD', function () {
  it('Renders a Card', function () {
    const component = shallow(<TBD />);
    console.log(component.debug());
    expect(component.equals(<Card/>)).is.equal(true);
  });
});

Debug output in console:

<Component title={[undefined]}>
TODO
</Component>

But I expect:

<Card title={[undefined]}>
TODO
</Card>

Upvotes: 1

Views: 1127

Answers (2)

sepulka
sepulka

Reputation: 405

Problem in Ant Delvelope components. Part of this components writed as simple anonymous functions, without extend React.Component, etc. In result Enzyme render it like <Component />, in browser it look like <StatelessComponent />.

Upvotes: 0

sminutoli
sminutoli

Reputation: 841

You don't need to test the whole connected component. I would test the presentational pure component first (as an unit test) and then you can test the connector in isolation.

I.E.

import React from 'react';
import {shallow}  from 'enzyme';
import {expect} from 'chai';
import chai from 'chai';
import chaiEnzyme from 'chai-enzyme';
chai.use(chaiEnzyme());
import { Card } from 'antd';
import {TBD} from '../src/js/components/TBD';

describe('TBD', function () {
  it('Renders a Card', function () {
    const component = shallow(<TBD />);
    expect(component.equals(<Card/>)).is.equal(true);
  });
  it('sets the right title', function () {
    const component = shallow(<TBD pathname="example" />);
    expect(component.prop('title')).is.equal("example");
  });
});

As you see, your pure component has to be tested as a pure function. You pass some props and expect some render.

Then when you test your connector, you can assert that it maps correctly the stateToProps and the dispatchToProps...

Upvotes: 1

Related Questions