Open anmoltw opened 5 years ago
Please fill out the entire issue template; it's there for a reason.
Thanks. Can you provide the full code for the component being tested, and the full code of the test?
ButtonGroup
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
export default class ButtonGroup extends PureComponent {
state = {
expanded: false
}
toggleExpand = () => {
this.setState(currentState => ({
expanded: !currentState.expanded
}));
}
render() {
return (
this.state.expanded ? this.props.values.map((value, index) => (
<div className="button" key={value.name + index}>
{value.name}
</div>
))
: (
<button type="button" className="button is-icon" onClick={this.toggleExpand}>
<span className="icon"><i className="fas fas fa-ellipsis-h" /></span>
</button>
)
);
}
}
import React from 'react';
import { shallow, mount } from 'enzyme';
import ButtonGroup from './ButtonGroup';
describe('<ButtonGroup />', () => {
describe('render', () => {
it('should toggle expanded state on click of button', () => {
const props = {
values: []
};
const component = shallow(<ButtonGroup {...props} />);
expect(component.state().expanded).toBeFalsy();
const expandButton = component.find('button');
expect(expandButton).toHaveLength(1);
expandButton.simulate('click');
expect(component.state().expanded).toBeTruthy();
});
});
Sidebar
import React, { Fragment } from 'react';
import { createPortal } from 'react-dom';
import PropTypes from 'prop-types';
import classNames from 'classnames';
export default class Sidebar extends React.Component {
toggle = () => {
this.setState(prevState => {
return { visible: !prevState.visible };
});
};
constructor(props) {
super(props);
this.state = {
visible: false,
animating: false,
direction: null,
setDirection: false
};
}
render() {
const classes = classNames(this.props.className, 'sidebar', 'overlay', 'very', 'wide');
return createPortal((
<div className={classes} id={this.props.id}>
<div className="sidebar-header">
<button type="button" className="button is-plain sidebar-closer is-medium" onClick={this.close}>
<span className="fas fa-lg fa-times" />
</button>
{this.props.title
&& typeof this.props.title === 'string'
? <h1 id="sidebar-heading" className="sidebar-title title is-1" data-testid="sidebar-title">{this.props.title}</h1>
: <Fragment>{this.props.title}</Fragment>
}
</div>
<div className="sidebar-wrapper" />
{this.props.children}
</div>
), document.querySelector('body'));
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import { shallow } from 'enzyme';
import Sidebar from './Sidebar';
describe('Sidebar component', () => {
let sidebarComp;
jest.useFakeTimers();
beforeAll(() => {
ReactDOM.createPortal = jest.fn((element) => {
return element;
});
});
beforeEach(() => {
sidebarComp = shallow(<Sidebar />);
});
afterEach(() => {
ReactDOM.createPortal.mockClear();
});
it('should toggle visible state value on toggle', () => {
expect(sidebarComp.state().visible).toBeFalsy();
sidebarComp.instance().toggle();
sidebarComp.update();
expect(sidebarComp.state().visible).toBeTruthy();
});
});
@anmoltw : I got it. You have to wrap map(JSX) output with <Fragment>
or <>
where as I didnt see any issue with SideBar testing
Here you go ==> https://codesandbox.io/s/w6183xxjr8 Refer: Hello.js : Line: 19,25 (wrapping)
I prefer to use props().onClick over simulate (thats Ok for this case) when using shallow mount (which I love too) Please let me know if any other issue after suggested change.
@ljharb Please add explanation/extra details if I missed any.
Thanks @pgangwani . That seems to work. However, the Sidebar issue still persists. @ljharb Any thoughts on that ?
@anmoltw sorry for the delay; can you prepare a new sandbox that highlights the remaining issue?
After updating enzyme version, a lot of tests seem to be failing for no reason. Here's a change history of my packages -
react: 16.4.2 -> 16.8.4 react-dom: 16.4.2 -> 16.8.4 enzyme: 3.3.0 -> 3.9.0 enzyme-adapter-react-16: 1.1.1 -> 1.11.2 react-test-renderer: 16.8.1 - 16.8.2
Expected value to be truthy, instead received false
51 | sidebarComp.instance().toggle(); 52 | sidebarComp.update(); 53 | expect(sidebarComp.state().visible).toBeTruthy(); 54 | });
toggle = () => { this.setState(prevState => { return { visible: !prevState.visible }; }); };
ShallowWrapper::update() can only be called when wrapping one node
37 | const expandButton = component.find('button'); 38 | expect(expandButton).toHaveLength(1); 39 | expandButton.simulate('click'); 40 | expect(component.state().expanded).toBeTruthy(); 41 | }); 42 | });