Sinon: Stub of an object property with getter/setter doesn't work

Created on 31 Mar 2016  路  8Comments  路  Source: sinonjs/sinon

If there's a method that was defined with defineProperty with a value it works, but not with get/set.

Error is "Attempted to wrap undefined property fnGetterSetter as function".

const sinon = require('sinon')

function factory() {
  let object = {}

  Object.defineProperty(object, 'fnValue', { configurable: true, value() { return 'fnValue' } })
  let fnGetterSetter = () => 'fnGetterSetter'
  Object.defineProperty(object, 'fnGetterSetter', {
    get() { return fnGetterSetter },
    set(newValue) { fnGetterSetter = newValue }
  })

  return object
}

let o1 = factory()

console.log('o1.fnValue: ' + o1.fnValue()) // => "fnValue"
console.log('o1.fnGetterSetter: ' + o1.fnGetterSetter()) // => "fnGetterSetter"
o1.fnGetterSetter = () => 'new fn'
console.log('o1.fnGetterSetter: ' + o1.fnGetterSetter()) // => "new fn"

let o2 = factory()

sinon.stub(o2, 'fnValue').returns('stubbed fnValue')
console.log('o2.fnValue: ' + o2.fnValue()) // works, => "stubbed fnValue"

sinon.stub(o2, 'fnGetterSetter').returns('stubbed fnGetterSetter') // fails - Attempted to wrap undefined property fnGetterSetter as function
console.log('o2.fnValue: ' + o2.fnGetterSetter())

Runnable code: https://tonicdev.com/56e1cbdb104098110026e06c/56fd90d539b35a13000ede79

1.x Bug Help wanted Needs investigation

All 8 comments

Already fixed in https://github.com/sinonjs/sinon/pull/1059. sinon@next will be updated tonight, but you can also depend on a commit as a workaround. Also reported in https://github.com/sinonjs/sinon/issues/1036.

npm show sinon dist-tags.next
2.0.0-pre.2

Hey, can someone confirm whether this works with the new version?

I'm running @elado's code snippet with [email protected] and I'm still seeing the error Attempted to wrap undefined property fnGetterSetter as function.

@mantoni Was your commit dropped somehow? You point to f7cba98bbdf0589185af156a26cc9fb3c1183dd8 as the solution to the problem, but I can't find that commit in master (could be failing at git-fu), and the problem is not fixed when I install sinon in either of these ways:

A gist showing what I'm still seeing in either version

@rclark I can find the commit in master when I go through the commit history, and the important change is still in current HEAD: https://github.com/sinonjs/sinon/blob/1e0b2373219668a9676fd11506117cb824006df2/lib/sinon/util/core/walk.js#L23

So I'm wondering if this was either re-introduced by some other change or if there is another issue.

Thanks for tracking that down @mantoni -- I would have to agree that either there was a regression or the commit you've indicated solved something other than this specific issue. It looks to me (having never worked on sinon before) like the issue is entirely in the wrap-method.js script.

In master, the problems starts here https://github.com/sinonjs/sinon/blob/1e0b2373219668a9676fd11506117cb824006df2/lib/sinon/util/core/wrap-method.js#L68, where methodDesc is defined as an object with a value property.

Then, here: https://github.com/sinonjs/sinon/blob/1e0b2373219668a9676fd11506117cb824006df2/lib/sinon/util/core/wrap-method.js#L86 the descriptor for the getter/setter only property that you intend to mock is asked for a .value property, which returns undefined.

Now the checkWrappedMethod() function will throw the error being reported, since it has been passed undefined: https://github.com/sinonjs/sinon/blob/1e0b2373219668a9676fd11506117cb824006df2/lib/sinon/util/core/wrap-method.js#L72.

A very simple failing test case indicating that the issue is not fixed:

var sinon = require('sinon');

var val;
var obj = {
  get foo() { return val; },
  set foo(v) { val = v; }
};

var stub = sinon.stub(obj, 'foo');

Thanks for tracking it down. Your research tells me that this is different issue than the one reported here, however with the same outcome. Reopening the issue.

Can you send a pull request adding the failing test? Or even have a stab at fixing it?

I've created a repository of demos with the following branches:

With [email protected] both spy() and stub() works for accessor methods
With [email protected], only stub() works for acessor methods. spy() fails with the following error message:

throw error;
                    ^

TypeError: Attempted to wrap undefined property myProperty as function

You can try it out yourself in this branch: https://github.com/mroderick/sinon-demo-getter-setter/tree/fail-in-1.17

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ljian3377 picture ljian3377  路  3Comments

optimatex picture optimatex  路  4Comments

brettz9 picture brettz9  路  3Comments

akdor1154 picture akdor1154  路  4Comments

JakobJingleheimer picture JakobJingleheimer  路  3Comments