In the documentation mockFn.mockResolvedValue(value) is described as a simple sugar function for jest.fn().mockImplementation(() => Promise.resolve(value)), but I noticed a different behaviour when using ES2018 Promise finally().
The tests pass with mockImplementation() but fail with mockResolvedValue() and return this error: finally is not a function.
Use ES2018 Promise finally() in your application (importing babel-polyfill for example) and try to test it with mockResolvedValue() and mockImplementation().
The result should be the same with both implementations.
Here is a simple example.
Node: 8.11.1
Jest: 23.2.0 (empty config)
Babel: 6.23.0 (babel-preset-env)
Babel-polyfill: 6.26.0
Is there a workaround for tests with code using finally() until this is resolved?
In my tests I imported babel-polyfill in the setupTestFrameworkScriptFile file and when I need to mock a function that returns a promise, I use the jest.fn().mockImplementation(() => Promise.resolve(value)) syntax instead of jest.fn().mockResolvedValue(value) .
I'm not sure it's the right way to do but it works.
Thanks @VictorCazanave that worked for me
A slightly shorter workaround is jest.fn().mockReturnValue(Promise.resolve(value)) - also works.
Curiously, the code in jest actually does simply call mockImplementation(() => Promise.resolve(value)):
https://github.com/facebook/jest/blob/f8efff95431dd079abf8ae02b8e541e3019d211b/packages/jest-mock/src/index.js#L512
It looks like the issue might be in the way how ES polyfills patch finally in. I guess that somehow jest runtime captures the 'native' instance of Promise function, while unit test scripts capture a patched version with another prototype. I mean, I did see 2 different prototypes for Promise while debugging - one with finally and one without.
Curiously, the code in jest actually does simply call
mockImplementation(() => Promise.resolve(value)):
jest/packages/jest-mock/src/index.jsLine 512 in f8efff9
f.mockImplementation(() => Promise.resolve(value));
It looks like the issue might be in the way how ES polyfills patchfinallyin. I guess that somehow jest runtime captures the 'native' instance ofPromisefunction, while unit test scripts capture a patched version with another prototype. I mean, I did see 2 different prototypes forPromisewhile debugging - one withfinallyand one without.
I have the same issue. But it is so weird. I passed all my unit test at local computer. And then I push it to Github then it was failed some test cases on Drone CI tool. Which as I understand is the same root cause with you.
I have followed the guide to change mockResolvedValue to mockImplementation. However, it didn't work to me. I have digged deep to the library to see what really happening and it is the same like you talk about.

Now I am trying to find what I have to do next.
I found a solution for this and I think that this is root cause(my project use Vuejs).
In my webpack.base.conf I saw this line of code.
entry: {
app: ["babel-polyfill", "./src/main.js"]
},
It mean we add babel-polyfill before we run our bundle file in order to allow it pack polyfill in.
So In my setup.js. I added import "babel-polyfill" and it work perfectly.
Bumped into this issue while adding jest to an Angular-CLI project.
Tried importing babel-polyfill in setup.js to no avail.
Been having this issue as well. I can add in a .finally polyfill, but mockResolvedValue seems to avoid it somehow.
I also have a similar issue (not obviously related to .finally though). I'm testing a React component that has several synchronous calls and mocking the return values of those calls.
When I use
mockedFunction.mockResolvedValue({ success: true })
the test fails (due to not actually waiting for the mocked promise to resolve), but when I use
mockedFunction.mockImplementation(() => Promise.resolve({ success: true }))
it works as expected.
Was a fix found for this?
@lgc13 I did this to get around it:
mockImplementationOnce(() => Promise.resolve("response"))
The solution for me was to start using Node 10+ which supports finally.
Most helpful comment
Curiously, the code in jest actually does simply call
mockImplementation(() => Promise.resolve(value)):https://github.com/facebook/jest/blob/f8efff95431dd079abf8ae02b8e541e3019d211b/packages/jest-mock/src/index.js#L512
It looks like the issue might be in the way how ES polyfills patch
finallyin. I guess that somehow jest runtime captures the 'native' instance ofPromisefunction, while unit test scripts capture a patched version with another prototype. I mean, I did see 2 different prototypes forPromisewhile debugging - one withfinallyand one without.