googleapis / nodejs-common

🚀🐢 A set of classes and utilities used in Google npm modules.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Reduce dependency on proxyquire

JustinBeckwith opened this issue · comments

The next step in our transition into TypeScript is to move towards es6 style modules. This helps ensure the d.ts is rich, and gives us a lot of the type safety we're looking for.

While trying this out, I ran into a roadblock with our usage of proxyquire in the tests. Proxyquire depends on the ability to globally mutate the behavior of a function on a given module. With es modules... this isn't really possible anymore without some sort of DI abstraction.

In most cases, it didn't feel like the use of complete module overriding was needed. Would it be possible to rewrite some of the tests so they do mocking at the network (nock) or file system level instead of the module level? While it does mean running more unrelated code in unit tests, it would significantly reduce test complexity, and give more weight to end to end scenarios.

Looking for help with this one :) @stephenplusplus @callmehiphop

Welp, this is a tricky one. I'm not sure about this module, but applying this thought forward to our others, proxyquire is used for much more than blocking network requests. For example, we make sure the methods were properly promisified (this is done through our common module), and much more-- here's just one example from the first file I picked to show an example: https://github.com/googleapis/nodejs-storage/blob/fb88bd16b25e80962e630a300632d0d15817682c/test/file.js#L118-L125

  • Stubbing gcs-resumable-upload allows us to see that we are passing the correct user options to the third party module
  • Stubbing hash-stream-validation allows us to fake hashing validation failures and successes, to see if our code reacts properly

I'm definitely open to new testing strategies (like, if you read my bullet points above and were like, "Oh, that's terrible-- the right way to do that is ____"). If mocking modules is correct, however, and proxyquire simply isn't compatible with es modules, is there another solution we can look at?

I totally hear what you're saying. I spent a few hours yesterday trying to work around this, and it uh... wasn't exactly fun 😂The mocking you're doing makes a lot of sense 👍

I think was running into problems because I was trying to just directly export functions instead of using an object instance. I was specifically looking at util.ts. Let me take a shot at using an es6 class, and exporting an instance of the class instead of directly exporting the functions. After sleeping on it, I suspect that would let proxyquire keep on proxyquiring.

With all of the files converted over to es modules, I think we've done what we needed to do here.