Unable use mock servise worker in react testing library

Instead of mocking an axios request, I try to test the component using msw, but after the request I don't get the visibility of the content in the component, what am I doing wrong?

My component

import React, {useEffect, useState} from 'react'
import axios from "axios";


export default function TestPage() {

  const [testData, setTestData] = useState('')

  useEffect(() => {
    const getSomeData = async () => {
      const data = await axios.get('https://jsonplaceholder.typicode.com/todos/1')
      setTestData(data.data.title)
    }
    getSomeData()
  }, [])

  return (
      <div className='test'>
        <h1>{testData}</h1>
      </div>
  )
}

My test file

import React from 'react'
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import {render, act, screen} from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import TestPage from "../testPage";


const allUsers = [
  {title:'User'}
]

const server = setupServer(
    rest.get('https://jsonplaceholder.typicode.com/todos/1', async (req, res, ctx) => {
      return res(ctx.json( {data: allUsers} ));
    })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers())
afterAll(() => server.close());

test('loads and displays greeting', async () => {
  await act(async () => {
    await render(<TestPage/>)
  })
  await screen.findByText('User') //I have no response content here
  screen.debug()
})

Upvotes: 1

Views: 3349

Answers (1)

Lin Du
Lin Du

Reputation: 102487

You do not need to define the data field for ctx.json(), the resolved value of the axios.get() method has a data field. See Response schema

In addition, the data returned by the API is an array.

You don't need to use the act helper function, wait for the result of the API call operation in your test by using one of the async utilities like waitFor or a find* query is enough.

E.g.

TestPage.tsx:

import React, { useEffect, useState } from 'react';
import axios from 'axios';

export default function TestPage() {
  const [testData, setTestData] = useState('');

  useEffect(() => {
    const getSomeData = async () => {
      const res = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
      console.log(res.data);
      setTestData(res.data[0]?.title);
    };
    getSomeData();
  }, []);

  return (
    <div className="test">
      <h1>{testData}</h1>
    </div>
  );
}

TestPage.test.tsx:

import React from 'react';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import TestPage from './TestPage';

const allUsers = [{ title: 'User' }];

const server = setupServer(
  rest.get('https://jsonplaceholder.typicode.com/todos/1', async (req, res, ctx) => {
    return res(ctx.json(allUsers));
  })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

describe('67902700', () => {
  test('loads and displays greeting', async () => {
    render(<TestPage />);
    await screen.findByText('User');
    screen.debug();
  });
});

test result:

 PASS  examples/67902700/TestPage.test.tsx (7.499 s)
  67902700
    ✓ loads and displays greeting (65 ms)

  console.log
    [ { title: 'User' } ]

      at examples/67902700/TestPage.tsx:10:15

  console.log
    <body>
      <div>
        <div
          class="test"
        >
          <h1>
            User
          </h1>
        </div>
      </div>
    </body>

      at logDOM (node_modules/@testing-library/dom/dist/pretty-dom.js:82:13)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        7.978 s

Upvotes: 3

Related Questions