Feature: getters & setters#692
Conversation
|
My issue with this is that if you need to stub out properties, you probably shouldn't be using getters, but functions. Getters are nice for accessing private data or making quick computations over other data, but in my mind, anything complicated enough warranting stubbing out in tests seems just like bad design for me. It has always been a design goal for Sinon not to enable or make it too easy to do stupid things. Can you come up with some convincing use cases for this? If we do go for this, and I think @mantoni and @mroderick should pitch in as well, I'm not ecstatic about the suggested API. I think we should either have a dedicated function, like sinon.stub(object, 'property', propertyDescriptor);That last one will be a little more verbose, which is a good thing. Maybe it'll make people think twice. As a last note, I personally feel that a better solution is to have a section on stubbing properties in the docs, laying down the case that you shouldn't do it, would be preferable. But it's not up to me alone. |
|
Like @cjohansen, I wouldn't want to add an API for this, for the said reasons. However, I understand the need to stub a property that was defined with a getter. I'd use the existing sandbox functionality, but this does not work at the moment: var sinon = require('sinon');
var o = {};
Object.defineProperty(o, 'p', { get : function () { return 1; }, configurable : true });
var s = sinon.sandbox.create();
s.stub(o, 'p', 2); // TypeError: Cannot set property p of #<Object> which has only a getter |
|
My own use case of this is to stub a configuration class, which abstracts over a key value store. Getters and setters are used to interact with the store. I then provide the getter with a value, test whether the setter is called with the appropriate value, called only once, etc. I could use functions instead, but I personally find the getter/setter approach to be simpler. I think this is more of a design preference, but if it is not convincing enough, I'm sure many others would also like the chime in here. I agree with @mantoni that adding new APIs is not ideal, but I cannot see how both getters and setters can be used with the existing api. I'll update my PR with @cjohansen last api as it does look a lot better than mine. |
|
@cjohansen I've switched over now to your last interface. |
|
Build is failing |
|
@cjohansen Could you run the build again? Only 0.10 is failing and it says "this potentially indicates a stalled build", could be a travis issue. |
|
Re-started the build, it passed |
|
Thanks for your work on this. Let's hope people won't use it too much ;) |
|
Just a heads up, but this change broke sinon.js for IE<9 as it uses ES5 methods. Trying to fix it locally, it's a current WIP. |
|
Is this documented yet? |
|
+1 for documentation |
|
Finally working example to stub getter: var o = {
get foo() { return 'foo' }
};
sinon.stub(o, 'foo', { get: function () { return 'foo stubbed' }});
console.log(o.foo); // foo stubbed |
|
In the example above, Similarly when using |
|
@novemberborn : I do not know. Maybe some of the others might. |
|
@simonzack This seems to have introduced a regression affecting Chrome. See #1046. Could you have a look? |
Spying on the methods of the localStorage object failed to work in Chrome when Sinon started using `Object.defineProperty`. Instead, the effect was to add a key with the name of the method (say "getItem") to the disk storage, instead of on the actual localStorage object. This seems to only affect Chrome. Closes sinonjs#1046
Spying on the methods of the localStorage object failed to work in Chrome when Sinon started using `Object.defineProperty`. Instead, the effect was to add a key with the name of the method (say "getItem") to the disk storage, instead of on the actual localStorage object. This seems to only affect Chrome. Closes sinonjs#1046
Spying on the methods of the localStorage object failed to work in Chrome when Sinon started using `Object.defineProperty`. Instead, the effect was to add a key with the name of the method (say "getItem") to the disk storage, instead of on the actual localStorage object. This seems to only affect Chrome. Closes sinonjs#1046
Spying on the methods of the localStorage object failed to work in Chrome when Sinon started using `Object.defineProperty`. Instead, the effect was to add a key with the name of the method (say "getItem") to the disk storage, instead of on the actual localStorage object. This seems to only affect Chrome. Closes sinonjs#1046
Spying on the methods of the localStorage object failed to work in Chrome when Sinon started using `Object.defineProperty`. Instead, the effect was to add a key with the name of the method (say "getItem") to the disk storage, instead of on the actual localStorage object. This seems to only affect Chrome. Closes #1046
Fix regression in sinonjs#692 by falling back to simple property assignment. A repack of sinonjs#1098 for the branch. See that for details
Fix regression in sinonjs#692 by falling back to simple property assignment. A repack of sinonjs#1098 for the `master` branch. See that for details
Fix regression in sinonjs#692 by falling back to simple property assignment. A repack of sinonjs#1098 for the `master` branch. See that for details
This PR addresses #88. I didn't touch mock as I've read about the plans to remove it in 2.0.
I've tried to make as little modification to the existing codebase as possible, and integrated getters & setters by providing an additional
typeparameter, which can take the valuegetorset. UsingdefinePropertyand friends also solves #690.Example usage:
@cjohansen I understand that you're not really a fan of getters & setters, but a lot of people do have a need for this (see above issue). Since sinon is the best (and only) mocking framework around, I think that getter & setter support will really benefit the community.