Reputation: 1287
I have a connected container like so:
import React from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { autobind } from 'core-decorators';
const propTypes = {
data: PropTypes.object,
userData: PropTypes.object,
};
class ConnectedContainer extends React.Component {
@autobind
doSomethingImportant() {
...
}
render() {
....
}
}
ConnectedContainer.propTypes = propTypes;
const mapStateToProps = state => ({ data, userData });
const mapDispatchToProps = (dispatch) => {
return { actions: bindActionCreators(actions, dispatch) };
};
export default connect(mapStateToProps, mapDispatchToProps)(ConnectedContainer);
I want to test doSomethingImportant
, so I have test like so:
import React from 'react';
import { shallow } from 'enzyme';
import ConnectedContainer from '.....'';
import configureStore from 'redux-mock-store';
const mockStore = configureStore();
const store = mockStore({ getState: () => null, dispatch: () => null, data: { data from fixture }, userData: { data from fixture } });
const container = (
<ConnectedContainer
store={store}
actions={{}}
/>
);
describe('ConnectedContainer', () => {
describe('doSomethingImportant', () => {
it('returns something important', () => {
const wrapper = shallow(container);
expect(wrapper.instance().doSomethingImportant()).to.equal( ... some output here );
});
});
});
And no matter what I do, I get this error:
TypeError: wrapper.instance(...). doSomethingImportant is not a function
What is happening with my container that I'm unable to access its instance methods?
Upvotes: 3
Views: 2729
Reputation: 8652
Export the ConnectedContainer class itself, not the wrapped version. You want to test your code, not the connect() function.
You can keep the default export as the wrapped component, and then add the word export
in front of the class definition:
export class ConnectedContainer extends React.Component { // Named export, for testing purposes only
...
}
Then in your test, import { ConnectedContainer } from '....'
Render that with shallow
instead of the default export.
Also, naming your component ConnectedContainer
is very confusing! It only becomes connected after it is wrapped with the connect function. So when you export ConnectedContainer
(as I've suggested) you're actually exporting a non-connected component class. (And is it actually a container? That's also pretty vague.)
One naming convention people use is to define a constant that holds the return value of connect(), and name that xxxContainer, like so:
export class IconView extends React.Component { // Exported for testing
// ... class implementation
}
function mapStateToProps(){...}
function mapDispatchToProps(){...}
const IconViewContainer = connect(mapStateToProps, mapDispatchToProps)(IconView);
export default IconViewContainer; // Exported for use as a component in other views
Upvotes: 5
Reputation: 9978
Try:
const Container = (
<ConnectedContainer
store={store}
actions={{}}
/>
);
Note, the only difference is the C uppercase in container. The thing is that React only treats classes and methods as components if they start with a capital letter. That could be your problem.
Upvotes: 0