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

Add throwOnNotFound method #225

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

jacobsmith-fusionalliance

Add an optional configuration function, similar in API to noCallThru,
that will force Proxyquire to throw an error if one of the stub keys is
not resolvable. Currently, it silently stubs out a module that is not
utilized by the object being proxyquired.

The intended use case is to aid in refactoring and debugging. Test
suites may optionally enable this feature so that developers get a
meaningful message when they attempt to proxyquire an import that is not
used, as, generally, this is a result of forgetting to update a
proxyquire statement after changing the name or imports of a module.

===

Thanks for all your work on proxyquire - myself and the team I am on have gotten some real use out of it! I have found that additional information when refactoring code would be helpful (i.e., we rename foobar.js => foobarFunction.js, forget to update our proxyquire({ 'foobar': ... }), and then the proxyquired object calls out to the actual foobarFunction, possibly having side effects or just generally making debugging a bit more difficult.

Please let me know if you want any changes to this PR (and no hard feelings if it's not something you want to bring in to the mainline (: ) - thanks!

Add an optional configuration function, similar in API to noCallThru,
that will force Proxyquire to throw an error if one of the stub keys is
not resolvable. Currently, it silently stubs out a module that is not
utilized by the object being proxyquired.

The intended use case is to aid in refactoring and debugging. Test
suites may optionally enable this feature so that developers get a
meaningful message when they attempt to proxyquire an import that is not
used, as, generally, this is a result of forgetting to update a
proxyquire statement after changing the name or imports of a module.
Copy link
Collaborator

@bendrucker bendrucker left a comment

Choose a reason for hiding this comment

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

Hi! Open to this with:

  • A new name (imports)
  • Consideration for whether you should be able to enable this for a single stub a la @noCallThru

@@ -140,6 +153,10 @@ Proxyquire.prototype._resolveModule = function (baseModule, pathToResolve) {
paths: Module.globalPaths
})
} catch (err) {
if (this._throwOnUnresolvedImports) {
throw new ProxyquireError('Invalid stub: "' + pathToResolve + '" is not required by the proxyquired object')
Copy link
Collaborator

Choose a reason for hiding this comment

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

Inclined to just re-throw here

@jacobsmith-fusionalliance
Copy link
Author

Great, thanks for those comments! I've updated the code with the new name and the error handling like you mentioned.

I'm not sure about adding this to a single stub - in my own uses, noCallThru is something we've implemented at the file level, so I don't have any personal experience adding this to a single stub. It seems like this particular addition would not be as useful on a per-stub basis because the ultimate goal is to make sure that the Subject Under Test really does require everything that you are proxying over, so in my mind it only makes sense at the higher "module" level.

* @private
* @return {object} The proxyquire function to allow chaining
*/
Proxyquire.prototype.throwOnUnresolved = function () {
Copy link
Collaborator

Choose a reason for hiding this comment

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

throwOnNotFound is the best I can come up with. Handling unresolved stubs is more of a description of how proxyquire works as opposed to what the user wants.


describe('when I pass a stub with a key that is not required on the proxyquired object', function () {
function act () {
const proxyquireThrowOnUnresolved = proxyquire.throwOnUnresolved()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
const proxyquireThrowOnUnresolved = proxyquire.throwOnUnresolved()
proxyquire.throwOnUnresolved()

The return value is the main fn itself—assigning the return value implies a new copy of proxyquire which isn't the case here. This test mutates state it doesn't own and I'd rather that be apparent in case it causes future issues.

Choose a reason for hiding this comment

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

Ah yes, thanks for pointing that out! I've been using a generator function most of the time around proxyquire to have a "clean slate" for each test run so forgot it was actually mutating here!

@jacobsmith-fusionalliance jacobsmith-fusionalliance changed the title Add throwOnUnresolvedImports method Add throwOnNotFound method Oct 29, 2018
Copy link
Collaborator

@bendrucker bendrucker left a comment

Choose a reason for hiding this comment

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

Thanks! If you add docs to this to the readme I can merge and release.

@jacobsmith-fusionalliance
Copy link
Author

Alright, the README has been updated - let me know if you'd like any changes! Thanks!

@jacobsmith-fusionalliance
Copy link
Author

Hi @bendrucker - just wanted to follow up here. Thanks!

Copy link
Collaborator

@bendrucker bendrucker left a comment

Choose a reason for hiding this comment

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

Left a comment on the docs. It's not sufficiently true to the behavior as written. I'm happy to knock out a grammar/clarity edit at the end but I want to make sure we agree on the substance.

Chain-ability with other methods (e.g. noCallThru) is implied but unimportant. What is important is that proxquire will only try to load your stub paths from disk when callThru is enabled. Set noCallThru and then throwOnNotFound does nothing. It's important to make this clear to users. This change does not validate all your stub paths if you don't enable call thru. Perhaps it should—that's still open for discussion as far as I'm concerned.

README.md Outdated Show resolved Hide resolved
@@ -127,6 +127,41 @@ Two simple steps to override require in your tests:
- therefore specify it exactly as in the require statement inside the tested file
- values themselves are key/value pairs of functions/properties and the appropriate override

## Raise error if proxying a modulePath that the module under test does not reference

By default `proxyquire` will stub out modulePaths, whatever their path may be.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do not line-wrap Markdown

@@ -127,6 +127,41 @@ Two simple steps to override require in your tests:
- therefore specify it exactly as in the require statement inside the tested file
- values themselves are key/value pairs of functions/properties and the appropriate override

## Raise error if proxying a modulePath that the module under test does not reference

By default `proxyquire` will stub out modulePaths, whatever their path may be.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Avoid "stub out," it's unclear what that means. It's also not true, as the sentence is written.

@bendrucker
Copy link
Collaborator

Sorry for the delay and thanks for keeping after it. Had some significant concerns with the docs and the behavior in general and just wrote them up.

@samuelms1
Copy link

Just realized I opened a PR that does the same thing as this. See #228

@samuelms1
Copy link

Actually - on second thought this PR is different from mine (#228). The feature I was trying to add was to force all dependencies to have a registered stub whereas this one seems to error if the path to a module was not found so the throwOnNotFound is appropriately named.

Co-Authored-By: jacobsmith-fusionalliance <[email protected]>
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.

3 participants