如何使用Jest模拟用户模块中的取消导出(私有)函数

时间:2018-10-21 06:18:09

标签: javascript jestjs

我有一个“私有”功能,该功能包装了API请求的通用功能,还有一堆“公共”功能,可以使用请求配置对象触发实际的请求(请参见requestUploadStatementFile文件中的以下内容)。

我正在尝试测试这些公共函数,但不确定如何使用Jest(在这种情况下为requestWithAutoTokenRenew函数)来模拟私有函数。

/**
 * An API wrapper which auto renew JTW once it get expired
 *
 * @param {Object} requestConfig Request configuration object
 * @returns {Promise}
 */
const requestWithAutoTokenRenew = async requestConfig => {
  const session = await doGetSession();
  const sessionToken = session.idToken.jwtToken;
  const { url, method, params, payload } = requestConfig;
  const requestObj = {
    url,
    method,
    headers: {
      Accept: "application/json",
      Authorization: sessionToken,
      "Content-Type": "application/json"
    },
    data: payload,
    ...params
  };

  return axios.request(requestObj).then(response => response.data);
};

/**
 * Upload bank or credit card statement for parsing
 *
 * @param {Object} file Statement PDF file needs to be parsed
 */
export const requestUploadStatementFile = file => {
  const requestConfig = {
    url: URL_UPLOAD,
    method: "POST",
    payload: file
  };

  return requestWithAutoTokenRenew(requestConfig);
};

1 个答案:

答案 0 :(得分:1)

我采用的解决方法不是模拟整个“私有”功能,而是“私有”功能内部功能的“不可能”部分。在这种情况下,请从远程服务doGetSession获取令牌,然后使用Axios lib request方法调用外部API。

// Mocks
import { request } from "axios";
import { doGetSession } from "../utilities/auth/auth";

// Targets
import { requestUploadStatementFile } from "./api";

jest.mock("../utilities/auth/auth");
jest.mock("axios");

describe("requestUploadStatementFile", () => {
  it("should fire request with correct reqeust configuration object", done => {
    doGetSession.mockImplementationOnce(() => {
      return Promise.resolve({ idToken: { jtwToken: "SAMPLE-TOKEN" } });
    });

    request.mockImplementationOnce(() => {
      return Promise.resolve({ data: [] });
    });

    requestUploadStatementFile({}).then(transactions => {
      const transactionsExpected = [];
      const requestExpectedArgs = {
        data: {},
        headers: { Accept: "application/json", Authorization: undefined, "Content-Type": "application/json" },
        method: "POST",
        url: "https://*.*.amazonaws.com/api/upload"
      };

      expect(transactions).toEqual(transactionsExpected);
      expect(request).toHaveBeenCalledTimes(1);
      expect(request).toHaveBeenCalledWith(requestExpectedArgs);

      done();
    });
  });
});

感谢@felixmosh的评论。

  

模拟私有功能被认为是不好的做法。您应该始终仅模拟应用程序的外层,通常是公共API