5

I'm using Mocha + Chai and axios-mock-adapter for testing my axios request. It workes well, but I don't know how to test headers of axios by axios-mock-adapter and make sure Authorization and Content-type is correct!

export const uploadFile = (token: string, fileName: string, file: Buffer): Promise<string> => {
  return new Promise((resolve, reject): void => {
    const uploadFileURL = `xxxxx.com`;
    axios
      .put(uploadFileURL, file, {
        headers: {
          Authorization: `Bearer ${token}`,
          "Content-type": "application/x-www-form-urlencoded",
        },
      })
      .then((response): void => {
        resolve(response.data.id);
      })
      .catch((error: Error): void => {
        reject(error.message);
      });
  });
};

And this is my test function

  describe("uploadFile", (): void => {
    let mockAxios: MockAdapter;
    beforeEach((): void => {
      mockAxios = new MockAdapter(axios);
    });

    afterEach((): void => {
      mockAxios.reset();
    });

    it("should return item's id", (done): void => {
      const fileName: string = faker.system.fileName();
      const token: string = faker.random.words();
      const file: Buffer = Buffer.from(faker.random.words());
      const expectedResult = {
        id: faker.random.uuid(),
      };
      mockAxios.onPut(`xxxxx.com`).reply(200, expectedResult, {
        Authorization: `Bearer ${token}`,
        "Content-type": "application/x-www-form-urlencoded",
      });

      uploadFile(token, fileName, file)
        .then((actualResult: string): void => {
          // I want to test my header of my requests
          expect(actualResult).to.equal(expectedResult.id);
          done(); // done make sure we know when we run the test
        })
        .catch(done);
    });
  });

So if anyone know how to write correct test for the header request, please help me. Thanks in advance!

Sergey Gubarev
  • 777
  • 3
  • 11
  • 29
Tran B. V. Son
  • 459
  • 6
  • 21

1 Answers1

7

The only way by now is accessing request headers in .reply and validate it here:

mockAxios.onPut(`xxxxx.com`).reply((config) => {
  expect(config.headers."Content-Type").toEqual("What do you expect here");
  return [200, expectedResult, {
    Authorization: `Bearer ${token}`,
    "Content-type": "application/x-www-form-urlencoded",
  }];
});

Actually I believe it should also be possible in declarative way:

mockAxios.onPut(`xxxxx.com`, undefined, { 
  expectedHeader1: "value1", 
  expectedHeader2: "value2"}
).reply(200, expectedResult);

So it would just throw instead of returning mock response if request headers did not match.

But it does no work this way by now.

Reason: axios-mock-adapter uses deepEqual for such a filtering. So we would need specify there not just few required headers(we are focusing on) but all headers including those axios adds on its own(like Accept). So it is not really readable.

I've filed #219 in their repo on this. If it was not intentional for any reason, that may be fixed in future.

skyboyer
  • 15,149
  • 4
  • 41
  • 56
  • Thanks for your help. But I dont think we need `mock` the `headers`, just return `[200, expectedResult], becuase in `uploadFile`, we use both Authorization and `Content-type`. But anyway, good answer! – Tran B. V. Son Oct 11 '19 at 07:41
  • @TranB.V.Son actually I did copy your code sample :) since I cannot know if something in `then` chain may rely on those headers present in response. But sure, if you don't need that you don't need that. – skyboyer Oct 11 '19 at 07:50