diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
index 5167a51b4..60ef105d6 100644
--- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
+++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
@@ -1319,7 +1319,7 @@ describe('shallow', () => {
render() {
return (
- {this.props.id}
+ {this.props.foo}
);
}
@@ -1330,6 +1330,144 @@ describe('shallow', () => {
expect(wrapper.find('.bar')).to.have.lengthOf(1);
});
+ describe.only('merging props', () => {
+ it('merges, not replaces, props when rerendering', () => {
+ class Foo extends React.Component {
+ render() {
+ return (
+
+ {this.props.foo}
+
+ );
+ }
+ }
+
+ const wrapper = shallow();
+
+ expect(wrapper.debug()).to.equal(`
+
+ bar
+
+ `.trim());
+ expect(wrapper.props()).to.eql({
+ className: 'foo',
+ children: 'bar',
+ });
+ expect(wrapper.instance().props).to.eql({
+ id: 'foo',
+ foo: 'bar',
+ });
+
+ wrapper.setProps({ id: 'bar' });
+
+ expect(wrapper.debug()).to.equal(`
+
+ bar
+
+ `.trim());
+ expect(wrapper.props()).to.eql({
+ className: 'bar',
+ children: 'bar',
+ });
+ expect(wrapper.instance().props).to.eql({
+ id: 'bar',
+ foo: 'bar',
+ });
+ });
+
+ itIf(is('> 0.13'), 'merges, not replaces, props on SFCs', () => {
+ function Foo({ id, foo }) {
+ return (
+
+ {foo}
+
+ );
+ }
+ const wrapper = shallow();
+
+ expect(wrapper.debug()).to.equal(`
+
+ bar
+
+ `.trim());
+ expect(wrapper.props()).to.eql({
+ className: 'foo',
+ children: 'bar',
+ });
+ if (is('< 16')) {
+ expect(wrapper.instance().props).to.eql({
+ id: 'foo',
+ foo: 'bar',
+ });
+ }
+
+ wrapper.setProps({ id: 'bar' });
+
+ expect(wrapper.debug()).to.equal(`
+
+ bar
+
+ `.trim());
+ expect(wrapper.props()).to.eql({
+ className: 'bar',
+ children: 'bar',
+ });
+ if (is('< 16')) {
+ expect(wrapper.instance().props).to.eql({
+ id: 'bar',
+ foo: 'bar',
+ });
+ }
+ });
+
+ it('merges, not replaces, props when no rerender is needed', () => {
+ class Foo extends React.Component {
+ shouldComponentUpdate() {
+ return false;
+ }
+
+ render() {
+ return (
+
+ {this.props.foo}
+
+ );
+ }
+ }
+ const wrapper = shallow();
+
+ expect(wrapper.debug()).to.equal(`
+
+ bar
+
+ `.trim());
+ expect(wrapper.props()).to.eql({
+ className: 'foo',
+ children: 'bar',
+ });
+ expect(wrapper.instance().props).to.eql({
+ id: 'foo',
+ foo: 'bar',
+ });
+
+ wrapper.setProps({ id: 'foo' });
+
+ expect(wrapper.debug()).to.equal(`
+
+ bar
+
+ `.trim());
+ expect(wrapper.props()).to.eql({
+ className: 'foo',
+ children: 'bar',
+ });
+ expect(wrapper.instance().props).to.eql({
+ id: 'foo',
+ foo: 'bar',
+ });
+ });
+ });
+
it('should call componentWillReceiveProps for new renders', () => {
const stateValue = {};
diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js
index 3aa18e78c..b355e7a9b 100644
--- a/packages/enzyme/src/ShallowWrapper.js
+++ b/packages/enzyme/src/ShallowWrapper.js
@@ -358,7 +358,7 @@ class ShallowWrapper {
}
// If it doesn't need to rerender, update only its props.
} else if (props) {
- instance.props = props;
+ instance.props = (Object.freeze || Object)({ ...instance.props, ...props });
}
this.update();
});