1

我正在尝试对发送发布请求的函数进行单元测试,然后 API 返回一个 json 对象。我正在尝试使用 jest 和fetch-mock-jest来做到这一点。

{"size":0,"timeout":0} 现在,测试函数接收并抛出错误,而不是预期的有效负载invalid json response body at reason: Unexpected end of JSON input。很确定有一些我看不到的基本内容。我在这方面花费的时间比我想承认的要多得多。

编辑:我对开玩笑和单元测试很陌生,所以如果有人有更好的建议来模拟 fetch,请告诉我。

测试文件

import fetchMock from 'fetch-mock-jest'

import {
  refreshAccessToken, isTokenExpired
} from '../../../lib/access/AccessToken'

describe('AccessToken Component...', () => {
it('...Refreshes AccessToken', async () => {
    const responseBody = { accessToken: taiDeveloperTokenValid } // The payload I want the AccessToken.refreshAccessTokento get
    setAccessToken(taiDeveloperTokenExpired)

    process.env.NEXT_PUBLIC_AUTH_API_HTTPS_URL = 'http://new-api.com'
    fetchMock.post(
      `${process.env.NEXT_PUBLIC_AUTH_API_HTTPS_URL}/refreshToken`,
      new Promise((res) =>
        setTimeout(
          () =>
            res({
              status: 200,
              body: JSON.stringify(responseBody),
              statusText: 'OK',
              headers: { 'Content-Type': 'application/json' },
            }),
          50,
        ),
      ),
    )
    const refreshAccessTokenResponse = await refreshAccessToken()
    expect(refreshAccessTokenResponse).toBe(true)
    expect(isTokenExpired()).toBe(false)
  })
  }

我正在测试的功能

import fetch from 'isomorphic-unfetch'

export const refreshAccessToken = async (): Promise<boolean> => {
  try {
    const response = await fetch(
      `${process.env.NEXT_PUBLIC_AUTH_API_HTTPS_URL}/refreshToken`,
      {
        method: 'POST',
        credentials: 'include',
      },
    )
    console.log(JSON.stringify(await response)) // this prints {"size":0,"timeout":0}
    const data = await response.json()
    accessToken = data.accessToken
    return true
  } catch (error) {
    console.log(error) // this prints  FetchError { message: 'invalid json response body at  reason: Unexpected end of JSON input', type: 'invalid-json'
    return false
  }
}

4

1 回答 1

0

您可以使用jest.mock(moduleName, factory, options)自己模拟isomorphic-unfetch模块。不需要fetch-mock-jest模块。

例如

main.ts

import fetch from 'isomorphic-unfetch';

export const refreshAccessToken = async (): Promise<boolean> => {
  try {
    const response = await fetch(`${process.env.NEXT_PUBLIC_AUTH_API_HTTPS_URL}/refreshToken`, {
      method: 'POST',
      credentials: 'include',
    });
    const data = await response.json();
    const accessToken = data.accessToken;
    console.log(accessToken);
    return true;
  } catch (error) {
    console.log(error);
    return false;
  }
};

main.test.ts

import { refreshAccessToken } from './main';
import fetch from 'isomorphic-unfetch';
import { mocked } from 'ts-jest/utils';

jest.mock('isomorphic-unfetch');

const fetchMocked = mocked(fetch);

describe('66009798', () => {
  afterAll(() => {
    jest.resetAllMocks();
  });
  it('should get access token', async () => {
    process.env.NEXT_PUBLIC_AUTH_API_HTTPS_URL = 'http://new-api.com';
    const data = { accessToken: '123' };
    const mResponse = { json: jest.fn().mockResolvedValueOnce(data) };
    fetchMocked.mockResolvedValueOnce(mResponse as any);
    const actual = await refreshAccessToken();
    expect(actual).toBeTruthy();
    expect(fetch).toBeCalledWith('http://new-api.com/refreshToken', {
      method: 'POST',
      credentials: 'include',
    });
    expect(mResponse.json).toBeCalledTimes(1);
  });
});

单元测试结果:

 PASS  examples/66009798/main.test.ts (13.604 s)
  66009798
    √ should get access token (37 ms)

  console.log
    123

      at examples/66009798/main.ts:11:13

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |   83.33 |      100 |     100 |      80 |
 main.ts  |   83.33 |      100 |     100 |      80 | 14-15
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        15.989 s
于 2021-02-03T02:09:03.583 回答