I'm mocking an axios instance using axios-mock-adapter for unit testing a service that connects to an API.
api.ts
export const api = axios.create({
baseURL: `${process.env.PUBLIC_URL}/api`,
});
answers.service.test.ts
import { api } from "../services/api";
import MockAdapter from "axios-mock-adapter";
describe("AnswersService", () => {
let mockAxios = new MockAdapter(api);
afterEach(() => {
mockAxios.reset();
});
Testing using practices recommended in the Jest documentation result in strange behaviour and failing tests.
There is something strange afoot:
- If I setup my test like this, it runs without trouble. However, if I remove the extra validations it shows that the api instance has not been called even once. Moreover, the test also fails if I run it with others, showing that
Received promise resolved instead of rejected
.
it("Should throw error when creating answer with invalid question ID", async () => {
const answer = "answer";
const idQuestion = -1;
let spy = jest.spyOn(api, "post");
mockAxios.onPost(`/answers/${idQuestion}`).reply(404);
await expect(createAnswer(answer, idQuestion)).rejects.toThrow(NotFoundError);
// expect(spy).toHaveBeenCalledWith(`/answers/${idQuestion}`, {
// body: answer,
// });
//expect(spy).toHaveBeenCalledTimes(1);
});
- If I modify the test so it uses a try-catch block, the test actually runs without issues but I get the warning that I shouldn't be calling expect conditionally.
it("Should throw error when creating answer with invalid question ID", async () => {
const answer = "answer";
const idQuestion = -1;
mockAxios.onPost(`/answers/${idQuestion}`).reply(404);
try {
await createAnswer(answer, idQuestion);
}
catch (e) {
expect(e).toBeInstanceOf(NotFoundError);
}
expect(jest.spyOn(api, "post")).toHaveBeenCalledWith(`/answers/${idQuestion}`, {
body: answer,
});
expect(jest.spyOn(api, "post")).toHaveBeenCalledTimes(1);
});
What could be going on? I don't understand what's going on. The first option seems to be the better one, but it just won't work.