I'm using the module rn-fetch-blob
to manage downloads in a React-Native Project. The module provides a StatefulPromise
class which is basically a promise with some added functionality. This added functionality is creating problems for my Jest unit tests. Here's the mock that had originally caused the problem (code within the file __mocks__/rn-fetch-blob.js
):
export default {
config: jest.fn(x => {
return {
fetch: jest.fn(x => Promise.resolve({ // <- I believe the problem lies here
info: () => {
return {status: 200}
}
}))
}
})
}
Somewhere within my code I had made a reference to one of the StatefulPromise methods (expire
). Unit tests covering that method are failing with this message:
filePromise.expire is not a function
.
My thinking was to then create my own StatefulPromise
for the sake of the tests:
class StatefulPromise extends Promise {
expire() {
jest.fn(() => {})
}
}
...
...
...
fetch: jest.fn(x => StatefulPromise.resolve({<same logic as before>});
This did not solve the problem.
I will note that this appears to work just fine in my browsers javascript console. The following surprised me as well:
let foo = StatefulPromise.resolve('foo');
console.log(foo instanceof StatefulPromise);
// true in console; false in jest
This has left me quite confused. Is there a better way to approach this problem?
StatefulPromise.resolve('foo') instanceof StatefulPromise
can be false if class inheritance went wrong. If it works in some environment but doesn't work in Jest this likely means that Jest wasn't correctly configured, and class inheritance is affected by Babel when it shouldn't. This shouldn't necessarily be a problem for this test but may be a problem later.
rn-fetch-blob
doesn't provide custom methods with inheritance. Even if it would, this usually doesn't impose a requirement to replicate class hierarchy in tests. There's no need to use third-party StatefulPromise
in tests that can change with time, as suggested in source code. Since a promise is supposed to behave like ES6 promise, it can be mocked with it and augmented if needed.
It's:
fetch: jest.fn(x => Object.assign(
Promise.resolve(...),
{ extend: jest.fn() }
)