I'm writing tests with Jest as a test runner, trying to mock a server using the Mock Server Library (https://mswjs.io/). For some reason Jest seems not to await promises of Axios calls.
To isolate he problem I created a simple example: a Vue component that fires an axios post request to a test api, and then updates the template with a value from the response.
<template>
<div data-testid="test-page">
<h1>Test Page</h1>
<div data-testId="result-div" v-if="result_id">RESULT {{ result_id }}</div>
<form>
<button @click.prevent="submitForm()">Test Axios</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
result_id: null
}
},
methods: {
submitForm() {
axios.post('https://jsonplaceholder.typicode.com/posts',{
title: 'foo 2',
body: 'bar 2',
userId: 2,
}).then(
(response) => {
this.result_id = response.data.id;
}
);
}
}
}
</script>
<style scoped></style>
The jsonplaceholder.typicode.com post request docs are described here: https://jsonplaceholder.typicode.com/guide/
It returns this output
{
id: 101,
title: 'foo 2',
body: 'bar 2',
userId: 2
}
So once the response is returned and 'result_id' gets a value of 101, "RESULT 101" appears on the screen. In the browser it works perfectly.
But in Jest it doesn't. Here is the Jest test that fails:
import TestPage from './TestPage.vue';
import { render, screen } from '@testing-library/vue';
import "@testing-library/dom";
import "@testing-library/jest-dom"
import userEvent from '@testing-library/user-event';
import { setupServer } from 'msw/node'
import { rest } from "msw"
describe("Test Page", () => {
it("Tests axios", async () => {
const server = setupServer(
rest.post("https://jsonplaceholder.typicode.com/posts", (req, res, ctx) => {
return ctx.status(200);
})
);
server.listen();
render(TestPage);
const button = screen.queryByRole("button", { "name": "Test Axios" });
await userEvent.click(button);
await server.close();
const text = screen.queryByText("RESULT");
expect(text).toBeInTheDocument();
//const result_div = screen.queryByTestId("result-div");
//expect(result_div).toBeInTheDocument();
});
});
So I use msw to mock the server and return a 200 status, I then render the page, simulate the button click, and try to query the div containging the "RESULT 101" (using either queryByText or queryByTestId), but the v-if directive is never triggered and 'result_id' is not being set. So it seems like Jest doesn't await the axios promise and 'result_id' remains nulled instead of receiving the 101 value from the response.
Not sure if there's something wrong in my code, or it a Jest or even mswjs bug.