Jest fails to await axios promise breaking tests

Viewed 456

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.

0 Answers
Related