Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor stub methods #1239

Merged
merged 9 commits into from
Jan 25, 2017
Merged

Conversation

mroderick
Copy link
Member

@mroderick mroderick commented Jan 10, 2017

This PR refactors sinon.stub() and sandbox.stub() (internally collection.stub() methods to improve legibility.

Feedback on naming of files and functions as well as locations of these in the tree is most welcome.

The aim was to not make any changes to functionality, but make it easier to understand the stub methods and to highlight differences between them for future improvements.

During refactoring this, I discovered an inconsistency in the API.

Proposal: fix inconsistency of stubbing non-function properties

As you can see in collection.stub and its tests, it supports stubbing non-function properties, which sinon.stub does not.

The documentation for sandbox.stub reads:

The sandbox stub method can also be used to stub any kind of property. This is useful if you need to override an object's property for the duration of a test, and have it restored when the test completes

In my opinion, stubs should be used for replacing methods and objects with fakes. Instead of stubbing out a property on an object for the duration of a test, the author should use a stub in the right place to return an entirely fake object that has the (fake) methods and properties that is needed for the test.

I propose that we remove stubbing of non-function properties feature from collection.stub, so that it's behaviour matches that of sinon.stub (since it would then defer everything to sinon.stub).

I am happy to do that as part of this PR.

What do you think?

@mroderick mroderick force-pushed the refactor-stub-method branch from be2d032 to 9d64dbf Compare January 10, 2017 11:00
@mroderick mroderick force-pushed the refactor-stub-method branch from 9d64dbf to daa9ab4 Compare January 11, 2017 12:22
@coveralls
Copy link

coveralls commented Jan 11, 2017

Coverage Status

Coverage increased (+0.01%) to 94.885% when pulling daa9ab4 on mroderick:refactor-stub-method into eb15826 on sinonjs:master.


return stubbedObj;
if (isStubbingEntireObject) {
collectOwnMethods(stubbed).forEach(this.add.bind(this));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that it matters here, but you know that you can pass a custom this to forEach as the second argument?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did, don't use it much, as I try to avoid using this as I find it reduces problems when I do :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, but since you're using this here already ... 😆

@mantoni
Copy link
Member

mantoni commented Jan 11, 2017

This is quite a bit of cleanup! I like how you made things more readable by moving the complex decision making logic into separate modules. Looks all good to me.

Regarding the API inconsistency you spotted: I remember running into this as well a while back, but I think the only reason it wasn't cleaned up was laziness. It makes sense to fold this into the stub implementation instead of a collection-only feature.

@mroderick
Copy link
Member Author

It makes sense to fold this into the stub implementation instead of a collection-only feature.

My proposal was to remove it from collection.stub. Are you proposing that we add it to sinon.stub instead?

@mantoni
Copy link
Member

mantoni commented Jan 11, 2017

Oh, I didn't read careful enough then. I now remember that it's only implemented for sandboxes because there wouldn't be a possibility to restore the previous value, because the restore function is a property of the stub. I think it's a nice feature. We should keep it.

var walk = require("./util/core/walk");
var getPropertyDescriptor = require("./util/core/get-property-descriptor");
var valueToString = require("./util/core/value-to-string");
var failOnFalsyObject = require("./fail-on-falsy-object");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about throwOnFalsyObject - as this tells you explicitly what this will do. fail could mean many different things.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, that is a better name. I've renamed the file, the function and all the variables in new commits.

Thank you for the feedback 👍

@mroderick mroderick force-pushed the refactor-stub-method branch from daa9ab4 to d9fb4af Compare January 12, 2017 16:04
@mroderick mroderick force-pushed the refactor-stub-method branch from d9fb4af to e9e5ba2 Compare January 12, 2017 16:07
@coveralls
Copy link

coveralls commented Jan 12, 2017

Coverage Status

Coverage increased (+0.01%) to 94.885% when pulling e9e5ba2 on mroderick:refactor-stub-method into 1760b8c on sinonjs:master.

@coveralls
Copy link

coveralls commented Jan 12, 2017

Coverage Status

Coverage increased (+0.01%) to 94.885% when pulling e9e5ba2 on mroderick:refactor-stub-method into 1760b8c on sinonjs:master.

var wrapper;

deprecated.printWarning(
"sinon.stub(obj, 'meth', fn) is deprecated and will be removed from" +
Copy link
Member

@lucasfcosta lucasfcosta Jan 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, friends, I noticed that the third argument for the stub function is no longer going to be valid. While this seems to be okay when stubbing functions themselves I'd like to know how could we stub the get/set properties of descriptors.

Are we going to have a specific API for that or users should just use Object.getOwnPropertyDescriptor and then stub the get and set functions in there?

Also, if you want to take a look at how it works right now, #692 is the PR responsible for introducing it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, although I am not sure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucasfcosta that's an interesting discussion. I am not sure it should block merging of this PR. If you agree, would you mind opening a separate issue for the discussion, so we can merge this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I totally agree.

Let's discuss that in a separate issue, I've got some ideas for the API and how to implement it, I'd love to help with this. Also, this PR LG(reat)TM.

Awesome work, sir 😄

@mroderick
Copy link
Member Author

OK, since there are no objections, I am merging this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants