enzyme is not able to recognize my created child component - reactjs

I have a react component consist of my another component and I am using enzyme to test it. Here is my child component rendered in in parent component:
render() {
let returnVal = "";
returnVal = <SpinLoader/>
return (
returnVal
)
}
So for testing I have:
describe("confirmEmail component unit tests", () => {
before(() => {
confirmEmail = shallow(<ConfirmEmail {...props}/>);
});
// this tests that the Login exists and is not empty
describe("confirmEmail component exists", () => {
it("should not be empty", () => {
expect(confirmEmail).to.not.be.empty;
});
});
})
})
the above emptiness test fail since it is not able to recoginze spinloader however if I replace spinloader with a div then it will pass.
Any idea?
** Update:
As soon as I change the returnVal to
returnVal = <div><SpinLoader/></div>
it works.
so the problem is SpinLoader component which is not a standard element and it is my made component

Related

Using enzyme, How to find a child component in a component react if they are result of function return

I'm using jest/enzyme and want to check existence child elements of React component
if i have function as component child
const children = () => (
<>
<div>...</div>
<div>...</div>
</>
)
return <Component>{children}</Component>;
why i can't do like this
test('Should render div', () => {
wrapper = shallow(<MyComponent />);
const component = wrapper.find(Component);
expect(component.exists()).toBe(true); //return true
const children = wrapper.find('div')
expect(children.exists()).toBe(false); //return false
});
Your children function is basically a render prop and shallow doesn't render it. You can however trigger the rendering by calling it as a function like
shallow(
shallow(<MyComponent />)
.find(Component)
.prop('children')()
)
So your test will look like
test('Should render div', () => {
wrapper = shallow(<MyComponent />);
const component = wrapper.find(Component);
expect(component.exists()).toBe(true); //return true
const renderProp = shallow(component.prop('children')());
const children = renderProp.find('div');
expect(children.exists()).toBe(true);
});

react empty classlist attribute?

I'm new to react :)
If my component render looks like this:
render() {
return (
<object-search className="m-t-xs">
<div className="stats-title pull-left">
<h4>Object Search</h4>
and my tests are:
beforeEach(() => {
component = TestUtils.renderIntoDocument(<ObjectSearch {...props}/>);
renderedDOM = () => ReactDOM.findDOMNode(component);
});
it('should render with the correct DOM', () => {
const parent = renderedDOM();
expect(parent.tagName).toBe('OBJECT-SEARCH');
expect(parent.children.length).toBe(7);
expect(parent.classList[0]).toEqual('m-t-xs');
})
why am I seeing an empty classList attribute?
Home page ObjectSearch Rendering of ObjectSearch on componentDidMount should render with the correct DOM FAILED
Expected '' to equal 'm-t-xs'.
Note: using the karma test runner and jasmine

Test if function is called react and enzyme

I am trying to test one of the methods in my react component. It is being called after a button click so I have the simulation in place with enzyme
it('clone should call handleCloneClick when clicked', () => {
const cloneButton = wrapper.find('#clone-btn');
cloneButton.simulate('click');
});
My component method is here:
_handleCloneClick(event) {
event.preventDefault();
event.stopPropagation();
this.props.handleClone(this.props.user.id);
}
The _handleCloneClick is being called when the user clicks on the button thats in the simulation, how can I go about testing that its been called successfully?
There are two options, either you should spy on _handleCloneClick of component's prototype, before you render the component:
export default class cloneButton extends Component {
constructor(...args) {
super(...args);
this. _handleCloneClick = this. _handleCloneClick.bind(this);
}
_handleCloneClick() {
event.preventDefault();
event.stopPropagation();
this.props.handleClone(this.props.user.id);
}
render() {
return (<button onClick={this. _handleCloneClick}>Clone</button>);
}
}
And in your test:
it('clone should call handleCloneClick when clicked', () => {
sinon.spy(cloneButton.prototype, '_handleCloneClick');
const wrapper = mount(<cloneButton/>);
wrapper.find('#clone-btn').simulate('click');
expect(spy).toHaveBeenCalled() //adept assertion to the tool you use
});
Or, you can try to set a spy after rendering the component and invoke wrapper.update() afterwards:
it('clone should call handleCloneClick when clicked', () => {
const wrapper = mount(<cloneButton/>);
sinon.spy(wrapper.instance(), "_handleCloneClick");
wrapper.update();
wrapper.find('#clone-btn').simulate('click');
expect(spy).toHaveBeenCalled() //adept assertion to the tool you use
});

Testing input.focus() in Enzyme

How do I test input.focus() in enzyme. I am writing the script with react. My code is below:
public inputBox: any;
componentDidUpdate = () => {
setTimeout(() => {
this.inputBox.focus();
}, 200);
}
render() {
return (
<div>
<input
type = 'number'
ref = {element => this.inputBox = element } />
</div>
);
}
You can use mount instead of shallow.
Then you can compare document.activeElement and the input DOM node for equality.
const output = mount(<MyFocusingComponent/>);
assert(output.find('input').node === document.activeElement);
See https://github.com/airbnb/enzyme/issues/316 for more details.
Per React 16.3 updates... using createRef for anyone visiting this post today, if you rearrange the original component to use the new ref api
class InputBox extends PureComponent {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
componentDidMount() {
this.inputRef.current.focus();
}
render() {
return (
<input
ref={this.inputRef}
/>
);
}
}
Then in your test spec
it("Gives immediate focus on to name field on load", () => {
const wrapper = mount(<InputBox />);
const { inputRef } = wrapper.instance();
jest.spyOn(inputRef.current, "focus");
wrapper.instance().componentDidMount();
expect(inputRef.current.focus).toHaveBeenCalledTimes(1);
});
Notice the use of the inputRef.current attribute which references the currently assigned DOM node.
Other approach is to test if element gains focus, i.e. focus() is called on node element. To achieve this, focused element need to be referenced via ref tag like it takes place in your example – reference was assigned to this.inputBox. Consider example below:
const wrapper = mount(<FocusingInput />);
const element = wrapper.instance().inputBox; // This is your input ref
spyOn(element, 'focus');
wrapper.simulate('mouseEnter', eventStub());
setTimeout(() => expect(element.focus).toHaveBeenCalled(), 250);
This example uses Jasmine's spyOn, though you can use any spy you like.
I just had the same issue and solved using the following approach:
My setup is Jest (react-create-app) + Enzyme:
it('should set the focus after render', () => {
// If you don't create this element you can not access the
// document.activeElement or simply returns <body/>
document.body.innerHTML = '<div></div>'
// You have to tell Enzyme to attach the component to this
// newly created element
wrapper = mount(<MyTextFieldComponent />, {
attachTo: document.getElementsByName('div')[0]
})
// In my case was easy to compare using id
// than using the whole element
expect(wrapper.find('input').props().id).toEqual(
document.activeElement.id
)
})
This worked for me when using mount and useRef hook:
expect(wrapper.find('input').get(0).ref.current).toEqual(document.activeElement)
Focus on the particular element can be checked using selectors.
const wrapper = mount(<MyComponent />);
const input = wrapper.find('input');
expect(input.is(':focus')).toBe(true);
Selecting by data-test attribute or something similar was the most straight forward solution I could come up with.
import React, { Component } from 'react'
import { mount } from 'enzyme'
class MyComponent extends Component {
componentDidMount() {
if (this.inputRef) {
this.inputRef.focus()
}
}
render() {
return (
<input data-test="my-data-test" ref={input => { this.inputRef = input } } />
)
}
}
it('should set focus on mount', () => {
mount(<MyComponent />)
expect(document.activeElement.dataset.test).toBe('my-data-test')
})
This should work
const wrapper = mount(<MyComponent />);
const input = wrapper.find('input');
expect(input).toHaveFocus();

Way to test the order of elements in React

Just want to implement the unit test for my react component with using the Jest and Enzyme.
Is there a way to test the order? Let's say I have component Button, and I want to render icon and text at the same time.
And of course it's good to provide the alignment option to the user(Icon first or Children first).
Button.js
class Button extends React.Component {
constructor() {
super();
}
render() {
let content;
const icon = (<Icon type='search' />);
if (this.props.iconAlign === 'right') {
content = (<span>{this.props.children} {icon}</span>
} else {
content = (<span>{icon} {this.props.children}</span>
}
return (
<button>{content}</button>
);
}
}
How to test the iconAlign props with Jest and Enzyme?
Check on the type of the component
Check icon first
var button = TestUtils.renderIntoDocument(<Button />);
var buttonNode = ReactDOM.findDOMNode(button);
expect(buttonNode.props.children[0].type.name).toEqual("Icon")
You could use a shallow render and compare the output. I am not familiar with the Jest syntax so that side of my example may be incorrect (I quickly referred to their website):
import { shallow } from 'enzyme';
describe(`Button`, () => {
it(`should render the icon on the right`, () => {
const children = <div>foo</div>;
const actual = shallow(
<Button iconAlign="right" children={children} />
);
const expected = (
<button><span>{children} <Icon type='search' /></span></button>
);
expect(actual.matchesElement(expected)).toBeTruthy();
});
});
And then you could create another test for the "left" align.
The enzyme version of #pshoukry's answer.
describe(`Button`, () => {
it(`should render icon on the right`, () => {
const wrapper = shallow(
<Button iconAlign="right">
<div>foo</div>
</Button>
);
const iconIsOnRight = wrapper.find('span').childAt(1).is(Icon);
expect(iconIsOnRight).toBeTruthy();
});
});
For reference, here is the enzyme shallow rendering API documentation: https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md

Resources