diff --git a/docs/README.md b/docs/README.md index 575deabdb..5ed68b03a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -30,6 +30,7 @@ * [closest(selector)](/docs/api/ShallowWrapper/closest.md) * [shallow()](/docs/api/ShallowWrapper/shallow.md) * [render()](/docs/api/ShallowWrapper/render.md) + * [unmount()](/docs/api/ShallowWrapper/unmount.md) * [text()](/docs/api/ShallowWrapper/text.md) * [html()](/docs/api/ShallowWrapper/html.md) * [get(index)](/docs/api/ShallowWrapper/get.md) diff --git a/docs/api/ShallowWrapper/unmount.md b/docs/api/ShallowWrapper/unmount.md new file mode 100644 index 000000000..59d252510 --- /dev/null +++ b/docs/api/ShallowWrapper/unmount.md @@ -0,0 +1,34 @@ +# `.unmount() => Self` + +A method that unmounts the component. This can be used to simulate a component going through +an unmount/mount lifecycle. + +#### Returns + +`ShallowWrapper`: Returns itself. + + + +#### Example + +```jsx +const spy = sinon.spy(); + +class Foo extends React.Component { + constructor(props) { + super(props); + this.componentWillUnmount = spy; + } + render() { + return ( +
+ {this.props.id} +
+ ); + } +} +const wrapper = shallow(); +expect(spy.calledOnce).to.equal(false); +wrapper.unmount(); +expect(spy.calledOnce).to.equal(true); +``` diff --git a/docs/api/shallow.md b/docs/api/shallow.md index cb9c838f7..6526c2ada 100644 --- a/docs/api/shallow.md +++ b/docs/api/shallow.md @@ -103,6 +103,9 @@ Shallow renders the current node and returns a shallow wrapper around it. #### [`.render() => CheerioWrapper`](ShallowWrapper/render.md) Returns a CheerioWrapper of the current node's subtree. +#### [`.unmount() => ShallowWrapper`](ShallowWrapper/unmount.md) +A method that un-mounts the component. + #### [`.text() => String`](ShallowWrapper/text.md) Returns a string representation of the text nodes in the current render tree. diff --git a/src/ShallowWrapper.js b/src/ShallowWrapper.js index 15a9e7486..832e70605 100644 --- a/src/ShallowWrapper.js +++ b/src/ShallowWrapper.js @@ -324,6 +324,16 @@ export default class ShallowWrapper { return this.type() === null ? cheerio() : cheerio.load(this.html()).root(); } + /** + * A method that unmounts the component. This can be used to simulate a component going through + * and unmount/mount lifecycle. + * @returns {ShallowWrapper} + */ + unmount() { + this.renderer.unmount(); + return this; + } + /** * Used to simulate events. Pass an eventname and (optionally) event arguments. This method of * testing events should be met with some skepticism. diff --git a/src/react-compat.js b/src/react-compat.js index 991dd1352..ec3fa7215 100644 --- a/src/react-compat.js +++ b/src/react-compat.js @@ -1,5 +1,6 @@ /* eslint react/no-deprecated: 0 */ import { REACT013 } from './version'; +import objectAssign from 'object.assign'; let TestUtils; let createShallowRenderer; @@ -80,27 +81,27 @@ if (REACT013) { // shallow rendering when it's just a DOM element. createShallowRenderer = function createRendererCompatible() { const renderer = TestUtils.createRenderer(); + const originalRender = renderer.render; + const originalRenderOutput = renderer.getRenderOutput; let isDOM = false; let _node; - return { - _instance: renderer._instance, + return objectAssign(renderer, { render(node, context) { if (typeof node.type === 'string') { isDOM = true; _node = node; } else { isDOM = false; - renderer.render(node, context); - this._instance = renderer._instance; + return originalRender.call(this, node, context); } }, getRenderOutput() { if (isDOM) { return _node; } - return renderer.getRenderOutput(); + return originalRenderOutput.call(this); }, - }; + }); }; renderIntoDocument = TestUtils.renderIntoDocument; childrenToArray = React.Children.toArray; diff --git a/test/ShallowWrapper-spec.js b/test/ShallowWrapper-spec.js index d2fb8fd5b..4d7cb0762 100644 --- a/test/ShallowWrapper-spec.js +++ b/test/ShallowWrapper-spec.js @@ -1644,6 +1644,30 @@ describe('shallow', () => { }); + describe('.unmount()', () => { + it('should call componentWillUnmount()', () => { + const spy = sinon.spy(); + + class Foo extends React.Component { + constructor(props) { + super(props); + this.componentWillUnmount = spy; + } + render() { + return ( +
+ {this.props.id} +
+ ); + } + } + const wrapper = shallow(); + expect(spy.calledOnce).to.equal(false); + wrapper.unmount(); + expect(spy.calledOnce).to.equal(true); + }); + }); + describe('.render()', () => { it('should return a cheerio wrapper around the current node', () => {