Reputation: 325
I'm trying to unit test React Bootstrap modal dialog using Jasmine. But it is not working as expected.
Here is jsfiddle link using latest versions of React, React Bootstrap, Jasmine.: http://jsfiddle.net/30qmcLyf/3/
Test which fails:
line# 27-28
// This test fails. Find DOM Node.
var instanceDomNode = ReactDOM.findDOMNode(instance);
expect(instanceDomNode).not.toBe(null);
line# 39-40
//This test fails. Find modal header.
var headerComponents = TestUtils.scryRenderedComponentsWithType(component, ReactBootstrap.Modal.Header);
expect(headerComponents.length).not.toBe(0);
Also what is wrong with line#35-36. If I uncomment lines I get error shown in comments.
// Error: Did not find exactly one match for componentType:function ModalHeader()...
//var headerComponent = TestUtils.findRenderedComponentWithType(component, ReactBootstrap.Modal.Header);
//expect(headerComponent).not.toBe(null);
As per latest official documentation for test utilities (link), you are supposed to pass ReactComponent as first argument.
Can somebody tell me what is wrong?
Upvotes: 3
Views: 10460
Reputation: 96
In case you are using an older version of Enzyme, you can pass the container element to mount where you want your Modal to be rendered, like this:
Actual Code:
------------
import React from 'react'
import { Modal } from 'reactstrap'
export default MyModal = () => {
return (
<Modal isOpen={props.isOpen}>
<ModalHeader>Header</ModalHeader>
<ModalBody>Body</ModalBody>
</Modal>
);
}
Unit Test:
----------
import React from 'react'
import MyModal from './MyModal'
import { mount } from 'enzyme'
describe(() => {
let wrapper;
beforeEach(() => {
const container = document.createElement("div");
document.body.appendChild(container);
wrapper = mount( <MyModal isOpen={true}/> , {attachTo: container});
});
it('renders correctly', () => {
expect(wrapper).toMatchSnapshot();
expect(wrapper.find('ModalHeader')).toHaveLength(1);
expect(wrapper.find('ModalBody')).toHaveLength(1);
});
})
Upvotes: 1
Reputation: 8726
React-Bootstrap
modal can be unit tested using mount
of enzyme
it(componentToTest.title + 'renders Modal component', () => {
expect(wrapper.find(UVModal).length).toEqual(1);
});
it(componentToTest.title + 'renders major html elements', () => {
// Test whether modal-content element has 3 html children elements.
expect(wrapper.find('.modal-content').length).toEqual(1);
expect(wrapper.find('.modal-content').children()).toHaveLength(3);
// Test whether modal-header element has 2 html children elements.
expect(wrapper.find('.modal-header').length).toEqual(1);
expect(wrapper.find('.modal-header').children()).toHaveLength(2);
// Test whether modal-body element has 1 html child element.
expect(wrapper.find('.modal-body').length).toEqual(1);
expect(wrapper.find('.modal-body').children()).toHaveLength(1);
// Test whether modal-footer element has 1 html child element.
expect(wrapper.find('.modal-footer').length).toEqual(1);
expect(wrapper.find('.modal-footer').children()).toHaveLength(1);
elementToSearch = <p>Lannisters always pay their debt</p>;
expect(wrapper.contains(elementToSearch)).toEqual(false);
});
Check following blog for details:
https://medium.com/@yuvi1422/unit-test-react-bootstrap-modal-a37bf59732ab
Upvotes: 1
Reputation: 3997
Check out how the react-bootstrap team writes tests for this. The modal is rendered into a different subtree which is how it gets rendered to the document body and not directly as a child of its parent. In other words your srcying fails because the component is not in that Component tree.
You can use refs on the modal or look for the DOM nodes directly in the document.
Upvotes: 5