-
-
Notifications
You must be signed in to change notification settings - Fork 769
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
Possible to stub a standalone utility function? #562
Comments
Unfortunately not. |
For npm you can use https://github.com/thlorenz/proxyquire or similar. Michael Feathers would call this a link seam. It's not elegant, but doable. Once you have that in place, you can use Sinon as you normally would. In the long run, you might want to move your architecture towards object seams, but it's a solution that works today. Similar projects exist for RequireJS. |
Then you can stub require('./MyFunction').MyFunction and the rest of your code will without change see the stubbed edition. 💫 😵 💫 |
Stumbled across the same thing the other day, here's what I did: const proxyquire = require('proxyquire')
const sinon = require('sinon')
const sum = sinon.stub()
const ModuleWithDependency = proxyquire('module', {
'sum': sum
}) works pretty well for our case. |
If using CommonJS:
Note: Depending on whether you're transpiling you may need to do:
|
Often during tests I'll need to be inserting one stub for one specific test. The wrapper-function approach I took lets me modify the codebase and insert my stubs whenever I want, without having to either take a stub-first approach or play whack-a-mole with modules having references to the other modules I'm trying to stub and replace-in-place. I've had a number of code reviews where people have pushed me towards hacking at the Node module layer, via proxyquire, mock-require, &c, and it starts simple and seems less crufty, but becomes a very difficult challenge of getting the stubs needed into place during test setup. With proxyquire at least one can proxyquire() a micro-/fixture- sized version of the app, something top level, & all stubs will be brought in during it's load, but tackling this at a JS language level rather than Node module level continues to strike me as significantly more straightforward, and easier to manage consistently and without danger (caveat: so long as one remembers to restore). |
I made this module to more easily stub modules https://github.com/caiogondim/stubbable-decorator.js |
I was just playing with Sinon and found simple solution which seem to be working - just add 'arguments' as a second argument const sumStub = sinon.stub(sum, 'arguments');
sumStub.withArgs(2, 2).returns(4);
sumStub.withArgs(3, 3).returns(6); |
Try this import * as sum from './sum'
sinon.stub(sum, 'default', () => {
// stubbed function
}); |
@harryi3t - thanks that worked for me. |
@harryi3t That didn't work for me, using ES Modules. |
@elliottregan ES Modules are not stubbable per the STANDARD. We even have tests covering this behaviour. You can still do it, though, as I discuss here. A lot of people are not actually testing ES Modules, but transpiled ES Modules (using Webpack/Babel, etc). The resulting ES5 uses getters to emulate how ES Modules work. You might be doing that, but try the simple route I suggest in the linked thread. |
Possible workaround
|
@Sujimoshi Workaround for what exactly? What's the context for your fix? Also, where would people put the fix? In its current incarnation, it's missing a bit too much info to be helpful. It wouldn't help the original question and won't work for ES Modules. I am guessing that it concerns code that has been processed by Webpack 4, as it might apply (depending on your toolchain) to code written using ES2015+ syntax which have been transpiled into ES5, emulating the immutability of ES Modules through non-configurable object descriptors. |
deprecated now. |
…etCurrentUser due to version change It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 The test in App.test.tsx was failing when it tried to get the callCount for a stub for a free-standing function getCurrentUser, and currently, my package-lock.json has 3.9.5, so that appears to be why. My fix was to use an object where the functions become methods instead.
… we can stub them as part of the TypeScript 3.9.2+ update It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 The test in App.test.tsx was failing when it tried to get the callCount for a stub for a free-standing function getCurrentUser, and currently, my package-lock.json has 3.9.5, so that appears to be why. My fix was to use an object where the functions become methods instead.
It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 Currently, my package-lock.json has 3.9.5, so that appears to be why I was having these problems in my test. My fix was to use an object where the functions become methods instead.
It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 The solution is to make an object, FacultyAPI, that contains those functions and export the object instead of the functions themselves
…SchedulesForYear It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562
…etCurrentUser due to version change It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 The test in App.test.tsx was failing when it tried to get the callCount for a stub for a free-standing function getCurrentUser, and currently, my package-lock.json has 3.9.5, so that appears to be why. My fix was to use an object where the functions become methods instead.
… we can stub them as part of the TypeScript 3.9.2+ update It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 The test in App.test.tsx was failing when it tried to get the callCount for a stub for a free-standing function getCurrentUser, and currently, my package-lock.json has 3.9.5, so that appears to be why. My fix was to use an object where the functions become methods instead.
It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 Currently, my package-lock.json has 3.9.5, so that appears to be why I was having these problems in my test. My fix was to use an object where the functions become methods instead.
It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 The solution is to make an object, FacultyAPI, that contains those functions and export the object instead of the functions themselves
…SchedulesForYear It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562
It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562
I just rewrote my ES6 module from this:
to this:
It's a bit clunky, but enabled me to wrap the function in a stub. |
…etCurrentUser due to version change It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 The test in App.test.tsx was failing when it tried to get the callCount for a stub for a free-standing function getCurrentUser, and currently, my package-lock.json has 3.9.5, so that appears to be why. My fix was to use an object where the functions become methods instead.
… we can stub them as part of the TypeScript 3.9.2+ update It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 The test in App.test.tsx was failing when it tried to get the callCount for a stub for a free-standing function getCurrentUser, and currently, my package-lock.json has 3.9.5, so that appears to be why. My fix was to use an object where the functions become methods instead.
It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 Currently, my package-lock.json has 3.9.5, so that appears to be why I was having these problems in my test. My fix was to use an object where the functions become methods instead.
It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 The solution is to make an object, FacultyAPI, that contains those functions and export the object instead of the functions themselves
…SchedulesForYear It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562
It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562
It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562 Export Multi Year Plan function from the API so that it is no longer a free-standing function and can be used appropriately in the test and in the multi year plan code.
getMetadata cannot be exported as a standalone function. It turns out that you can no longer stub free-standing functions in Typescript 3.9.2+ according to this issue: microsoft/TypeScript#38568 sinonjs/sinon#562
now is almost 2021, is it possible? |
Not much different than 2019. |
You can do if you write import * as yourModule from ..
sinon.stub(yourModule, 'foo').returns(stuff) ps: this should be done before calling the original method or class. Eg: if you are using chai-http for integration tests you should call this stub before instanciating server |
@MarceloBD That is not true for a spec compliant ES2015+ environment and is not true for CommonJS. In fact, we explicitly detect and test for this case to give a good error message saying what is happening when it does not work: Your tip might be true if you utilize something that is not a spec compliant ESM environment, which is the case for some bundlers or if running using the excellent In any case, this issue from 2014 is really about CommonJS modules 😄 For the cases where your tip does apply, adding a small hint to the casual reader on what environment you are in (like "Webpack 5 + TypeScript 3.7 + Babel 10"/ link to config) will probably be useful for a lot of people 😻 . |
@MarceloBD 's solution works for me. We are using babel. Being able to stub a standalone function is a necessary feature for testing some functions. Not all functions are part of a class instance. |
And that's a good thing! Classes are hardly ever the right tool and is mostly just used as a crutch for people coming to JS from Java and C# land to make them feel more at home in the weird land of functions This still holds, though, @SSTPIERRE2 : you cannot stub standalone exported functions in a ES2015 compliant module (ESM) nor a CommonJS module in Node. That is just how these module systems work. It's only after transforming them into something else you might be able to achieve what you want. How you replace modules is totally environment specific and is why Sinon touts itself as "Standalone test spies, stubs and mocks for JavaScript" and not module replacement tool, as that is better left to environment specific utils (
And then you are probably no longer working with ES Modules, just something that looks like it. This is what Marcelo's suggestion looks like in Node:
which is just a friendly shield for what Node would otherwise tell you:
It cannot be done per spec. |
Many node modules export a single function (not a constructor function, but a general purpose "utility" function) as its "module.exports". Is it possible to use Sinon.js to stub this standalone function?
Is there any way to achieve this?
The text was updated successfully, but these errors were encountered: