I\'m trying to test a component which inherits context from a root component, without loading/rendering everything from the root down. I\'ve tried and searched for examples on h
I went into the same issue as you did and found out two ways of doing it.
The first one is a basic copycat of your own way: Create a wrapper around my component and inject it with a dynamic context. I put the source code below for those interested, because it's ES6 unlike your example. But it's just to show how it would be done in ES6 and I do NOT recommend anyone using it (I haven't actually tested it myself).
src/testUtils/mockWithContext.js
import React, { Component } from 'react';
import wrapDisplayName from 'recompose/wrapDisplayName';
import hoistStatics from 'recompose/hoistStatics';
export const defaultContext = {
permissions: [
],
user: {
id: '1',
display_name: 'Default user',
email: '+default.user@gmail.com', // Trick with "+" for infinite aliases using gmail.
username: 'default_user',
created: '2016-08-01T15:50:13.246Z',
},
};
export const defaultContextType = {
permissions: React.PropTypes.array,
user: React.PropTypes.shape({
id: React.PropTypes.string.isRequired,
display_name: React.PropTypes.string.isRequired,
email: React.PropTypes.string.isRequired,
username: React.PropTypes.string.isRequired,
created: React.PropTypes.string.isRequired,
}),
};
/**
* HOC for context
*/
const withContext = ({ context = defaultContext, contextType = defaultContextType }) => (WrappedComponent) => {
class WithContext extends Component {
getChildContext() {
return context;
}
render() {
return ;
}
}
WithContext.displayName = wrapDisplayName(WrappedComponent, 'WithContext');
WithContext.WrappedComponent = WrappedComponent;
WithContext.childContextTypes = contextType;
return WithContext;
};
export default hoistStatics(withContext);
As I said, I wrote it, but didn't test it because I found a much better way of doing context-injecting when trying to write tests for this mock.
Using Enzyme library, which is definitely built to support React components testing, there is the ability to shallow
/mount
/static
render your component, for testing purpose. And each of these methods allow a second argument: the context.
SimpleComponent.js
const SimpleComponent = React.createClass({
contextTypes: {
name: React.PropTypes.string,
},
render() {
return {this.context.name};
},
});
SimpleComponent.test.js
const context = { name: 'foo' };
const wrapper = mount( , { context });
expect(wrapper.text()).to.equal('foo');
wrapper.setContext({ name: 'bar' });
expect(wrapper.text()).to.equal('bar');
wrapper.setContext({ name: 'baz' });
expect(wrapper.text()).to.equal('baz');
Pretty straight-forward. I didn't use it yet but it looks like what I (and you) wanted to do. I guess I'll just have to throw my own implementation to the garbage.
http://airbnb.io/enzyme/docs/api/ReactWrapper/setContext.html