如何提高测试覆盖率Jest,酶

时间:2018-11-05 05:36:17

标签: reactjs jestjs enzyme

通过下面的代码,我可以获得66.27的分支覆盖率,并且矩阵仍然显示在第27行上可以进行一些改进。我进行了一些尝试和尝试,但对我没有任何帮助。任何建议将不胜感激。

矩阵

enter image description here

requestService.js

import axios from 'axios';
import HttpError from 'standard-http-error';


export const successResponse = response => (
  {
    status: response.status,
    data: response.data,
  }
);


export const throwHttpError = (error) => {
  if (error.response.data) {
    throw new HttpError(error.response.status, error.response.statusText, {
      data: error.response.data,
    });
  }

  throw new HttpError(error.response.status, error.response.statusText);
};

**line no: 27**
export default async (request, httpService = axios) => {
  const {
    method, url, data, headers,
  } = request;
  return httpService.request({
    method,
    url,
    headers: Object.assign({}, headers),
    data,
  }).then(successResponse, (error) => {
    throwHttpError(error);
  });
};

requestService.test.js

  import HttpError from 'standard-http-error';
import request, { successResponse, throwHttpError } from './requestService';

describe('requestService', () => {
  describe('successResponse', () => {
    const mockRes = {
      status: 9001,
      data: {
        stuff: 'stuff',
      },
    };
    it('should returns an object with only status and data properties', () => {
      const responseKeys = Object.keys(successResponse(mockRes));
      expect(responseKeys).toMatchObject(['status', 'data']);
      expect(responseKeys.length).toBe(2);
    });

    it('should map the status of the reponse to the status property', () => {
      expect(successResponse(mockRes).status)
        .toBe(mockRes.status);
    });

    it('should map the data of the reponse to the data property', () => {
      expect(successResponse(mockRes).data)
        .toMatchObject(mockRes.data);
    });

    it('should have a valid request object', async () => {
      const requestObj = {
        method: 'POST',
        url: 'http://mock.url',
        data: {},
        headers: {},
      };

      const mockRequest = jest.fn(() => Promise.resolve({}));

      const httpService = {
        request: mockRequest,
      };

      await request(requestObj, httpService);
      expect(mockRequest).toHaveBeenCalledWith({
        method: requestObj.method,
        url: requestObj.url,
        headers: {},
        data: requestObj.data,
      });
    });
  });

  describe('httpThrowError', () => {
    const mockErr = {
      response: {
        status: 9001,
        statusText: 'error message goes here',
      },
    };

    it('should map the status of the reponse to the error.status property', () => {
      try {
        throwHttpError(mockErr);
      } catch (e) {
        expect(e).not.toBe(null);
        expect(e.status).toBe(mockErr.response.status);
        expect(e.message).toBe(mockErr.response.statusText);
      }
    });

    it('should map the data of the reponse to the error.data property', () => {
      const mockErrWithData = Object.assign({}, mockErr);
      mockErrWithData.response.data = {};
      try {
        throwHttpError(mockErrWithData);
      } catch (e) {
        expect(e).not.toBe(null);
        expect(e.data).toBe(mockErrWithData.response.data);
      }
    });
  });

  describe('request', () => {
    const testCases = [
      ['should return error response on server error', 500],
      ['should return error response on bad request', 400],
      ['should return error response on unauthorised', 401],
    ];

    testCases.forEach(([testName, errorStatus]) => {
      it(testName, async () => {
        const errorResponse = {
          response: {
            status: errorStatus,
          },
        };
        const mockRequest = jest.fn(() => Promise.reject(errorResponse));

        const httpService = {
          request: mockRequest,
        };

        try {
          await request({ url: 'http://mock.url' }, httpService);
          throw new Error('Expected an exception, but none was thrown');
        } catch (err) {
          expect(err).not.toBe(null);
          expect(err).toMatchObject(
            new HttpError(errorResponse.response.status,
              errorResponse.response.statusText),
          );
        }
      });
    });

    it('should return an valid response (empty)', async () => {
      const response = {
        data: {
          meta: {},
          results: [],
        },
        status: 200,
        statusText: 'OK',
        headers: {},
        config: {},
        request: {},
      };

      const mockRequest = jest.fn(() => Promise.resolve(response));

      const httpService = {
        request: mockRequest,
      };

      const res = await request({ url: 'http://mock.url' }, httpService);

      expect(res).not.toBe(null);
      expect(res).toMatchObject(
        {
          status: response.status,
          data: response.data,
        },
      );
    });
  });
});



  [1]: https://i.stack.imgur.com/GErLI.png

1 个答案:

答案 0 :(得分:1)

由于throwHttpErrorrequest函数位于同一模块中,因此无法窥探throwHttpError,因此request的结果应类似于throwHttpError的方式进行测试经过测试。

应该是这样的:

const errorResponse = {
  response: {
    status: errorStatus,
  },
};
const mockRequest = jest.fn(() => Promise.reject(errorResponse));

const httpService = {
  request: mockRequest,
};

const resPromise = request({ url: 'http://mock.url' }, httpService);

await expect(resPromise).rejects.toMatchObject(
  new HttpError(errorResponse.response.status,
    errorResponse.response.statusText),
);