diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js
index 1ef78370c..86047d251 100644
--- a/packages/test-utils/src/wrapper.js
+++ b/packages/test-utils/src/wrapper.js
@@ -713,16 +713,6 @@ export default class Wrapper implements BaseWrapper {
     }
 
     Object.keys(data).forEach(key => {
-      if (
-        !this.vm ||
-        !this.vm.$options._propKeys ||
-        !this.vm.$options._propKeys.some(prop => prop === key)
-      ) {
-        throwError(
-          `wrapper.setProps() called with ${key} property which ` +
-          `is not defined on the component`
-        )
-      }
       if (
         typeof data[key] === 'object' &&
         data[key] !== null &&
@@ -736,6 +726,21 @@ export default class Wrapper implements BaseWrapper {
           `to trigger reactivity`
         )
       }
+      if (
+        !this.vm ||
+        !this.vm.$options._propKeys ||
+        !this.vm.$options._propKeys.some(prop => prop === key)
+      ) {
+        if (vueVersion > 2.3) {
+          // $FlowIgnore : Problem with possibly null this.vm
+          this.vm.$attrs[key] = data[key]
+          return
+        }
+        throwError(
+          `wrapper.setProps() called with ${key} property which ` +
+          `is not defined on the component`
+        )
+      }
 
       if (this.vm && this.vm._props) {
         // Set actual props value
diff --git a/test/specs/wrapper/setProps.spec.js b/test/specs/wrapper/setProps.spec.js
index 228cc7027..e7833a6be 100644
--- a/test/specs/wrapper/setProps.spec.js
+++ b/test/specs/wrapper/setProps.spec.js
@@ -2,6 +2,7 @@ import { compileToFunctions } from 'vue-template-compiler'
 import ComponentWithProps from '~resources/components/component-with-props.vue'
 import ComponentWithWatch from '~resources/components/component-with-watch.vue'
 import { describeWithShallowAndMount, vueVersion } from '~resources/utils'
+import { itDoNotRunIf } from 'conditional-specs'
 
 describeWithShallowAndMount('setProps', mountingMethod => {
   let info
@@ -38,18 +39,28 @@ describeWithShallowAndMount('setProps', mountingMethod => {
     expect(wrapper.is('div')).to.equal(true)
   })
 
-  it('throws error if component does not include props key', () => {
+  itDoNotRunIf(vueVersion > 2.3, 'throws error if component does not include props key', () => {
     const TestComponent = {
       template: '<div></div>'
     }
     const message = `[vue-test-utils]: wrapper.setProps() called ` +
-    `with prop1 property which is not defined on the component`
+      `with prop1 property which is not defined on the component`
     const fn = () => mountingMethod(TestComponent).setProps({ prop1: 'prop' })
     expect(fn)
       .to.throw()
       .with.property('message', message)
   })
 
+  itDoNotRunIf(vueVersion < 2.4, 'attributes not recognized as props are available via the $attrs instance property', () => {
+    const TestComponent = {
+      template: '<div></div>'
+    }
+    const prop1 = 'prop1'
+    const wrapper = mountingMethod(TestComponent)
+    wrapper.setProps({ prop1 })
+    expect(wrapper.vm.$attrs.prop1).to.equal(prop1)
+  })
+
   it('throws error when called on functional vnode', () => {
     const AFunctionalComponent = {
       render: (h, context) => h('div', context.prop1),