4

I'm trying to test a custom Material-ui React component with Enzyme but getting the following error:

ERROR: 'Warning: Failed context type: Required context 'muiTheme' was not specified in 'ChildComponent'.

What I've tried is to set a context according to this. The component that I want to reach and test is a child component.

const root = shallow(<RootComponent />, {context: {muiTheme}, childContextTypes: {muiTheme: React.PropTypes.object}})
const child = root.find(ChildComponent)
child.render() // <--- this line is throwing the error

update: this is related

Community
  • 1
  • 1
haxpanel
  • 4,402
  • 4
  • 43
  • 71

2 Answers2

2

I'm not sure this is the solution but it's one step closer to the goal.

const root = mount(<RootComponent />, {
  context: {muiTheme},
  childContextTypes: {muiTheme: React.PropTypes.object}
})
const child = root.find(ChildComponent)

Notice, I use mount instead of shallow. The issue is with this I can't use child.find({prop: 'value'}) any longer - return 0 items...

haxpanel
  • 4,402
  • 4
  • 43
  • 71
  • Here is a workaround for prop based selection: `const findChildComponent = propValue => root.findWhere(node => node.type() === ChildComponent && node.props().propName === propValue)` - obviously `propName` has to be replaced by the actual prop – haxpanel Oct 09 '16 at 13:05
1

You need to provide the <muiThemeProvider> component.

Here is an example on how to do :

import React from 'react';
import { mount } from 'enzyme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Input from './Input';

describe('<Input />', () => {
    const mountWithTheme = (node) => mount(<MuiThemeProvider>{node}</MuiThemeProvider>);

    it('calls componentDidMount', () => {
        sinon.spy(Input.prototype, 'componentDidMount');
        mountWithTheme(<Input />);
        expect(Input.prototype.componentDidMount.calledOnce).to.equal(true);
    });
});
Steeve Pitis
  • 4,283
  • 1
  • 21
  • 24
  • I've tried this as well. No luck: 1) renders the whole stuff and throws errors due to some invalid DOM thing (cant remember now) 2) did not solve the original issue – haxpanel Oct 07 '16 at 15:20
  • this code works for me. what is your `` – Steeve Pitis Oct 07 '16 at 15:23
  • Drawer > Menu > MenuItem. On the MenuItem I've got this param: `onTouchTap`. When using `mount()` I'm getting this: ERROR: 'Warning: Unknown prop `onTouchTap` on
    tag. Remove this prop from the element. For details, see .... in div (created by Overlay) in Overlay (created by Drawer) in div (created by Drawer) in Drawer (created by SideBar) in SideBar (created by Unknown) in Unknown'
    – haxpanel Oct 07 '16 at 15:26
  • `import injectTapEventPlugin from 'react-tap-event-plugin'; // Needed for onTouchTap // http://stackoverflow.com/a/34015469/988941 injectTapEventPlugin();` – Steeve Pitis Oct 07 '16 at 15:33
  • Wow, makes sense! But there is no way to test it with `shallow()`? – haxpanel Oct 07 '16 at 15:38
  • shallow will only render `` in this case. Don't know there is a way to shallow this. – Steeve Pitis Oct 07 '16 at 15:49
  • Yes thats clear, I was just expecting the context being passed down to the child components while calling `render()` on the sallow rendered item. It looks like your solution works. But let me have a quick question as using `mount()` broke the following: `drawer.find({primaryText: 'Homepage'})`. I can't find by attribute. Any idea? – haxpanel Oct 07 '16 at 15:55
  • Actually I've found out that you don't have to use the theme provider, it's enough to use `mount()` with the options mentioned in the question. – haxpanel Oct 07 '16 at 16:03