I'm writing some tests for an async node.js function which returns a promise using the Mocha, Chai and Sinon libraries.
Let's say this is my function:
function foo(params) {
return (
mkdir(params)
.then(dir => writeFile(dir))
)
}
mkdir
& writeFile
are both async functions which return promises.
I need to test that mkdir
is being called once with the params
given to foo
.
How can I do this?
I've seen quite a few examples on how to assert the overall return value of foo
(sinon-as-promised is super helpful for that) but non about how to make sure individual functions are being called inside the promise.
Maybe I'm overlooking something and this is not the right way to go?
mkdir
isn't called asynchronously here, so it's rather trivial to test:
mkdir = sinon.stub().resolves("test/dir")
foo(testparams)
assert(mkdir.calledOnce)
assert(mkdir.calledWith(testparams))
…
If you want to test that writeFile
was called, that's only slightly more complicated - we have to wait for the promise returned by foo
before asserting:
… // mdir like above
writeFile = sinon.stub().resolves("result")
return foo(testparams).then(r => {
assert.strictEqual(r, "result")
assert(writeFile.calledOnce)
assert(writeFile.calledWith("test/dir"))
…
})
You can mock the mkdir
function then use setTimeout
to check whether or not this function is called.
describe('foo', () => {
it('should call mkdir', () => {
return new Promise((resolve, reject) => {
let originalFunction = mkdir;
let timer = setTimeout(() => {
reject(`mkdir has not been called`);
});
mkdir = (...params) => new Promise(mkdirResolve => {
//restore the original method as soon as it is invoked
mkdir = originalMethod;
clearTimeout(timer);
mkdirResolve(someExpectedData);
resolve();
});
foo(params);
});
});
});