knee-cola/jest-mock-axios

.mockError throwing error because axios call not yet added to mock

btomasini opened this issue · 1 comments

I am testing an async method using axios, and am finding that the mockError is throwing an error because the request has not yet been added to the mock. I followed an example for using the library with an async method but still no luck. Any adivce is appreicated:

Secure.ts

    async loadFromCode(code: string, state: string | undefined) {

        const storage = await this.getStorage()
        if (!storage) {
            throw new Error('Nothing in storage')
        }
        const data = new FormData();
        data.set(grantTypeKey, 'authorization_code')
        data.set(codeKey, code)
        data.set(codeVerifierKey, storage.pkce.verifier)

        const res = await axios({
            method: 'POST',
            url: this.params.issuer + '/oauth/token',
            data: data,
            adapter: require('axios/lib/adapters/xhr'),
            headers: { 'Content-Type': 'multipart/form-data' }
        })

        const resp: TokenResponse = JSON.parse(res.data)

        this.authentication = {
            accessToken: resp.access_token,
            idToken: resp.id_token,
            refreshToken: resp.refresh_token,
            expiresIn: resp.expires_in,
        }
    }

Secure.test.ts

        describe('return with valid code and server error', () => {
            it('Handles server error', async () => {
                query = `?code=${code}`
                sessionStorage.__STORE__[storageKey] = JSON.stringify({
                    pkce: {
                        challenge: challenge,
                        verifier: verifier
                    },
                    state: state,
                    nonce: nonce
                })
                const err = new Error('Host cannot be reached')
                try {
                    const req = unit.loadFromCode('test', 'test')
                    mockAxios.mockError(err)
                    await req
                    fail('Expected exception')
                } catch (e) {
                    expect(e).toEqual(err)
                }
                const data = new FormData();
                data.set('grant_type', 'authorization_code')
                data.set('code', code)
                data.set('code_verifier', verifier)
                expect(mockAxios).toHaveBeenCalledWith({
                    method: 'POST',
                    url: issuer + '/oauth/token',
                    data: data,
                    headers: { 'Content-Type': 'multipart/form-data' }
                });

            })
        });

Result:

expect(received).toEqual(expected) // deep equality

    Expected: [Error: Host cannot be reached]
    Received: [Error: No request to respond to!]

      144 |                     fail('Expected exception')
      145 |                 } catch (e) {
    > 146 |                     expect(e).toEqual(err)
          |                               ^
      147 |                 }
      148 |                 const data = new FormData();
      149 |                 data.set('grant_type', 'authorization_code')

      at src/__tests__/Secure.test.ts:146:31
      at step (src/__tests__/Secure.test.ts:33:23)
      at Object.next (src/__tests__/Secure.test.ts:14:53)
      at src/__tests__/Secure.test.ts:8:71
      at Object.<anonymous>.__awaiter (src/__tests__/Secure.test.ts:4:12)
      at Object.<anonymous> (src/__tests__/Secure.test.ts:129:40)

The problem here is probably that mockError is executed right after await this.getStorage() and before await axios(), which results in the above error. Is there any way for you to move the getStorage or make sure that it resolves (and the code execution continues up to await axios) before the mockError call?