Is this not the correct way to render a react/reflux test with enzyme but without the store, ie, "dumb"
import React from 'react'
import { shallow, render } from 'enzyme'
import { Controls } from '../Controls' // named export
import LoadingSpinner from '../LoadingSpinner'
let wrapper
let loadingFlags = {
controls: true
}
describe('<Controls />', () => {
it('should render only the loading spinner', () => {
wrapper = shallow(<Controls loadingFlags={loadingFlags} />) // this ensures the spinner will show until data is ready
expect(wrapper.length).toEqual(1) // test passes
expect(wrapper.find(LoadingSpinner)).to.have.length(1)
// ^ TypeError: Cannot read property 'have' of undefined
})
})
When I log wrapper.html()
I can see the <img class='spinner' />
is rendered, but enzyme cannot find it as a component. To me, the docs indicate this is exactly what I should be doing. I suppose I could check for a child with that class, but that seems messier than checking for the component itself, eg the class changes within the Spinner component.
Using a component constructor allows Enzyme to pluck a child component in this way: const element = component. find(ChildComponent); This works well when there are one or two children.
Shallow rendering lets you render a component “one level deep” and assert facts about what its render method returns, without worrying about the behavior of child components, which are not instantiated or rendered. This does not require a DOM.
shallow method is used to render the single component that we are testing. It does not render child components. In Enzyme version less than 3, the shallow method does not have the ability to access lifecycle methods. But in Enzyme version 3, we have this ability.
Always begin with shallow. If componentDidMount or componentDidUpdate should be tested, use mount. If you want to test component lifecycle and children behavior, use mount. If you want to test children rendering with less overhead than mount and you are not interested in lifecycle methods, use render.
The test will work fine with shallow
, but the assertion has a TypeError because it doesn't exist - it looks like you are using Jest, but the enzyme docs show assertions using chai
BDD library.
Use the Jest equivalent instead:
expect(wrapper.find(LoadingSpinner)).toHaveLength(1)
You should use a mount().
from https://github.com/airbnb/enzyme/blob/master/docs/guides/jsdom.md
import test from 'ava';
import React from 'react';
import { mount, shallow, render } from 'enzyme'
import LoadingSpinner, {Controls} from './LoadingSpinner';
// jsdom init start
const { JSDOM } = require('jsdom');
const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
const { window } = jsdom;
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === 'undefined')
.map(prop => Object.getOwnPropertyDescriptor(src, prop));
Object.defineProperties(target, props);
}
global.window = window;
global.document = window.document;
global.navigator = {
userAgent: 'node.js',
};
copyProps(window, global);
// jsdom init end
test('<Controls />' , t => {
let wrapper = shallow(<Controls />);
let mntWrapper = mount(<Controls />);
t.true(wrapper.length == 1);
t.true(wrapper.find(LoadingSpinner).length === 1);
t.true(mntWrapper.find("img").length === 1);
t.true(mntWrapper.render().find('img').length === 1);
// if you need to test attributes check below.
t.true(mntWrapper.render().find('img')[0].attribs.src.indexOf('foo') >= 0);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With