Closed JacobFrericks closed 4 years ago
That's a bit confusing. Can you create a repo and I'll have a look?
Sorry for the delay, here is the repository: https://github.com/JacobFrericks/jest-temp/
Basically I used the "create-react-native-app" tool, installed the jest-fetch-mock module, then added the api.js and api.test.js from the examples and pasted them in. I changed one line in the test, expecting it to fail, but it still passes.
I believe you need to use the done
callback to let jest know when the test is finished, like so:
//api.test.js
import { APIRequest } from './api'
describe('testing api', () => {
beforeEach(() => {
fetch.resetMocks()
})
it('calls google and returns data to me', (done) => {
fetch.mockResponseOnce(JSON.stringify({ data: '12345' }))
//assert on the response
APIRequest('google').then(res => {
expect(res.data).toEqual('12345')
done()
})
//assert on the times called and arguments given to fetch
expect(fetch.mock.calls.length).toEqual(1)
expect(fetch.mock.calls[0][0]).toEqual('https://google.com')
})
})
I tried that, and it does indeed do what I want! All the tests fail when they should, and pass when they should. However, there is one weird thing.
If I change the last two expects to fail, say by changing the last one to be
expect(fetch.mock.calls[0][0]).toEqual('https://thisShouldFail.com')
I get the expected error:
Error: expect(received).toEqual(expected)
Expected value to equal:
"https://thisShouldFail.com"
Received:
"https://google.com"
However, if I change the first expect to be this:
expect(res.data).toEqual('67890')
I get an unexpected error:
Error: Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.
I expected something like "Expected value to equal: 12345 Received: 67890". Why did I get this other error?
Thank you for helping with this!
I updated my repository with the issue. If you run the test, you get the Async error.
@jefflau @IanVS does my issue make sense?
@JacobFrericks @jefflau @IanVS any update? I'm having the same problems
Guys, @JacobFrericks @jefflau @IanVS @linconkusunoki I think we are doing this wrong.
Let me explain to you.
Why don't you use async
instead of done
?
import { APIRequest } from './api'
describe('testing api', () => {
beforeEach(() => {
fetch.resetMocks()
})
it('calls google and returns data to me', async () => {
fetch.mockResponseOnce(JSON.stringify({ data: '12345' }))
//assert on the response
await APIRequest('google').then(res => {
expect(res.data).toEqual('12345');
});
// You can do this too
// const res = await APIRequest('google');
// expect(res.data).toEqual('12345');
//assert on the times called and arguments given to fetch
expect(fetch.mock.calls.length).toEqual(1);
expect(fetch.mock.calls[0][0]).toEqual('https://google.com');
})
})
I was having the same problem has you guys and one more. In my function, in this case APIRequest
, I needed to access to React Native
AsyncStorage
. To do this, I need to do it asynchronously. So I used async
and await
. It fixed my problem, BUT created another one. All the assertions after the call to the API function would not validate. I could put wrong values and it would still say they were valid.
The solution above solved everything for me, even the problem with the timeout:
Error: Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.
Give it a try and let me know if it worked for you!
@jefflau Maybe we should update the docs with this?
I was having the same issue with the first example. I got it to work by adding return
in front of the assert based on reading the Jest docs on promises.
Be sure to return the promise - if you omit this return statement, your test will complete before fetchData completes.
Docs should definitely be updated, because it can be very frustrating when one can't even get the most basic example to work correctly.
Glad I came across this, here was my solution
import { APIRequest } from './../src/api'
describe('testing api', () => {
beforeEach(() => {
fetch.resetMocks()
})
it('calls google and returns data to me', async () => {
expect.assertions(3);
fetch.mockResponseOnce(JSON.stringify({ data: '12345' }))
const res = await APIRequest('google');
//assert on the response
expect(res.data).toEqual('12345');
//assert on the times called and arguments given to fetch
expect(fetch.mock.calls.length).toEqual(1);
expect(fetch.mock.calls[0][0]).toEqual('https://google.com');
})
})
Made a PR to add @toklok's fix to the README
I'm talking about the "simple mock and assert" example. I copied the api.js and api.test.js exactly. I'll paste them here for reference
I tried changing each "expect" to verify the test fails. The last two work perfectly, it verified that https://google.com was called exactly once.
The first expect (inside the APIRequest) does not fail when I change it to 'abcde'. I put a console log right above the expect to make sure it's actually being run, and it printed no problem. I put another console log underneath the expect, and that is NOT being printed.
Why would this be happening? I'm running v1.6.2, Windows 10.