Closed cagross closed 3 years ago
tape has no built-in mocking; you may want to use npmjs.com/sinon for this. You can also use npmjs.com/sinon-sandbox, as well as t.teardown()
, to reset mocks after the test is done.
OK thanks very much for that. Do you think it would be helpful to add a blurb like this to the README? Not so much to inform people that Tape doesn't have built-in mocking--I think many will know/assume that. But moreso to point them in the right direction, to a solution that has worked well with Tape in the past (i.e. sinon). If so, let me know and I'd be happy to do that and submit a PR.
FYI I'm the same guy that submitted #541 and #542 :smiley:
We could, but in the entire ecosystem everyone really only uses one of two options: sinon, or jest builtin mocking - so I’m not sure how much clarity we need to provide.
OK then, sounds good. At least now there's a GitHub issue in the Tape repo on the subject, for people that are clueless about mocking (like I was :smile:).
I'll close this :-)
One approach you can take is to make non-trivial dependencies explicit. this makes the public API surface larger but makes writing tests simpler.
class myClass {
constructor (options = {}) {
this.myFetch = options.myFetch || (var) => {
if (env === 'node') throw 'Cannot run in Node';
}
}
myFunc() {
let myVar
this.myVar = 555
this.myFetch(this.myVar)
}
}
module.exports = { myClass }
tape('Tests description.', t => {
const myObj= myClass({ myFetch: () => {} })
const actual = myObj.myVal
const expected = 555
t.equal(actual, expected, 'Test description.')
t.end()
})
Another example of this pattern is using this.logger = options.logger
vs a global logger. Using a global logger is super convenient and using options.logger
is tedious but makes the code friendlier for tests.
That’s indeed how you’d do it if you wanted dependency injection to be part of your api.
OK thanks for that dependency injection example. I knew dependency injection was an option, but hadn't yet taken the time to understand what it was exactly. Your example made it pretty clear to me, which I appreciate a lot :-)
That’s indeed how you’d do it if you wanted dependency injection to be part of your api.
OK noted. Before moving forward with this, I'd definitely chat with my manager about it.
Hello.
I have a class method which has a secondary function defined inside of it (see code below). But the secondary function is designed to throw an exception when run in a Node environment. I'd like to run a Tape unit test to test this method. I don't need the secondary function at all in my test--it is irrelevant. But when I run my test (see test code below), as expected, an exception is thrown. With Tape, what are the suggested/typical ways to mock this secondary function, so I can still call this method in a unit test?
Is there a way to run my unit test and mock this secondary function (myFetchFunction) to a simple function that will not throw an error? In other words, during the unit test, set myFetchFunction() to some simple function, like console.log('Mocking function')
For example, I believe Jest has a way to do this, with their spyOn() method. I'm not complaining or demanding you have to be Jest :-) I'm just wondering how other Tape users have approached this.
Thanks in advance.
PS: I had a search through previous issues here, but nothing jumped out at me. Also, I didn't see anything in the README file about this. But after this exercise, if you want, I'd be happy to add a little blurb there, for future Tape users that might be wondering this.
edit: In hindsight, the function I want to mock in this case may be impossible to mock. Am I right there? If so, then I guess we can ignore the example I presented.
class.js
test.js