网站搜索

TypeScript - 当从单个方法多次调用 Axios 时模拟已解决的值


背景:我有一系列方法,它们将一起发起多个 axios 请求。在我的场景中,我必须先进行第一次 axios 请求以获取一些数据,然后我可以使用这些数据来生成第二次 axios 请求。之后,我还有第三次 axios 请求,它可能与前两次无关。

在我的测试中,我必须验证最后一次 axios 调用使用的 URL 是某个特定的 URL

问题: 当我验证 URL 时,我只得到第一次 axios 调用的结果。从我这边的故障排除来看,似乎 Jest 只执行第一次 axios 调用,或者我的解析值没有被正确解释。

问: 有没有办法让我在我的情景中尝试的事情能够实现?任何帮助都将不胜感激。

这是我尽力清理过的一部分代码。

主程序:

interface IPrerequisite {
  // Some implementation
}

class Prerequisite implements IPrerequisite {
  error = "";
  async checkStatus(token: string) {
    return Promise.resolve(true);
  }

  async getAxiosResponse(url: string, token: string) {
    const headers: AxiosRequestConfig = {
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        Authorization: `Bearer ${token}`,
      },
      timeout: timeoutDuration,
    };

    return axios
      .post(url, {}, headers)
      .then((res: AxiosResponse) => {
        return Promise.resolve(res.data);
      })
      .catch((err: AxiosError) => {
        return Promise.resolve("");
      });
  }
}

class ListKeysPrereq extends Prerequisite {
  constructor() {
    super();
  }
  async checkStatus(token: string) {
    // First axios request
    const firstResponse = await this.getAxiosResponse(url, token);
    if (firstResponse === "") {
      return Promise.resolve(false);
    }

    // Second axios request
      // Do some stuff with first response to pass to second request
    const secondResponse = await this.getAxiosResponse(url, token);
    if (secondResponse === "") {
      return Promise.resolve(false);
    }

    // Do some stuff with second response

    return Promise.resolve(true);
  }
}

class PrerequisiteFactory {
  static getInstance(prerequisite: string): IPrerequisite {
    switch (prerequisite) {
      case "LIST_KEYS_PREREQ":
        return new ListKeysPrereq();
      default:
        return null;
    }
  }
}

const checkConnectionPrerequisites = async (token: string) => {
  enum Prerequisites {
    LIST_KEYS_PREREQ,
  }

  for (const prereq in Prerequisites) {
    if (isNaN(Number(prereq))) {
      const prerequisite = PrerequisiteFactory.getInstance(prereq);
      const prerequisiteStatus = await prerequisite.checkStatus(token);
      if (!prerequisiteStatus) {
        return Promise.resolve(prerequisite.error);
      }
    }
  }

  return Promise.resolve("");
};

const getConnectionString = async (url: string, token: string, location: string): Promise<string> => {
  try {
    const prereqStatus = await checkPrerequisites(token);
    // Do some stuff
  } catch (err) {
    // Handle exception
  }

  // Last axios request
  return axios
    .post(url, {}, headers)
    .then((response: AxiosResponse) => {
      // Do something with the last response
      return Promise.resolve("sometext");
    })
    .catch((err: AxiosError) => {
      handleError(operationName, err);
      return Promise.resolve("");
    });
};

export const startProgram = async (token: string) => {
  connectionString = await getConnectionString(url, token, location);

};

Jest 测试

const postMock: jest.Mock = jest
  .fn()
  .mockResolvedValueOnce({
    status: 200,
    data: {
      someUri: "https://somefakestorageaccount.blob.core.contoso.com:443/somefakecontainer/somefakeblob",
    },
  })
  .mockResolvedValueOnce({ status: 200, data: { connectionString: "wss://thisfakestring/" } })
  .mockResolvedValueOnce({ status: 400 })
  .mockResolvedValue({ status: 200, data: { connectionString: "wss://thisfakestring/" } });

jest.mock("axios", () => {
  return {
    post: postMock,
  };
});

test("Sample Test", () => {
    const assertedUrl = "https://assertedurl.constoso.com/somecontainer/someblob";
    main.startprogram("token").then(() => {
      expect(postMock).toHaveBeenCalledTimes(1);
      expect(postMock.mock.calls[0][0]).toBe(assertedUrl); // This returns the call from only the first axios call
      expect(loadMock).toHaveBeenCalledTimes(4);
      expect(openMock).toHaveBeenCalledTimes(2);
    });
  });