Come testare un componente che recupera i dati in useEffect e le memorizza in stato di reagire-test-biblioteca e scherzo?

0

Domanda

Io sono abbastanza nuovo di reagire-test-biblioteca e in genere di test. Voglio testare un componente che recupera i dati da un API in useEffect gancio. Poi li memorizza in locale dello stato. Rende questi dati array array.mappa, ma io sto Error: Uncaught [TypeError: Cannot read properties of undefined (reading 'map')] errore. Probabilmente sto facendo di sbagliato nella mia suite di test, io ho studiato molto, ma non riuscivo a risolvere il problema.

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

    import { OnePiece } from '.';

    const server = setupServer(rest.get('server http address', (req, res, ctx) => {
        const totalData = [
            { name: "doffy", price: 100, image: "image url" },
            { name: "lamingo", price: 500, image: "image url" }
        ];
        return res(
            ctx.status(200),
            ctx.json({
                data: { crew: totalData }
            })
        )
    }))
    beforeAll(() => server.listen());
    afterAll(() => server.close());
    beforeEach(() => server.restoreHandlers());

    //console.log("mocking axios", axios)
    describe('OnePiece', () => {
        
        test('fetches the data from the API and correctly renders it', async () => {
            //Here's probably where i fail. Please someone tell me the right way :) 
            await render(<OnePiece />)
            const items = await screen.findAllByAltText('product-image');
            expect(items).toHaveLength(2);
            //     screen.debug()
        })
    })

E di seguito le parti di codice useEffect, e totalData.mappa il componente:

const [totalData, setTotalData] = useState([]);
const [crew, setCrew] = useState('straw-hat-pirates');

 useEffect(() => {
    let isApiSubscribed = true;
    const getOpData = async () => {
        const getCrews = await axios.get('http address');
        if (isApiSubscribed) {
            let data = getCrews.data;
            data = data[crew];
            // console.log("data", data);
            setTotalData(data);
        }
    }
    getOpData();
    return () => {
        isApiSubscribed=false;
    }
}, [crew])
.........

//in the return part
 <ProductsWrapper>
            {totalData.map((product, index) =>
                <ProductCard key={index} name={product.name} price={product.price} imageUrl={product.image} />
            )}
        </ProductsWrapper>
1

Migliore risposta

0

Come avevo previsto, il problema era il async recupero di dati. Attualmente setTimeOut è più che sufficiente per me, ma se qualcuno vede questo in futuro, si può guardare per il waitFor metodo di reagire-test-biblioteca. Ecco la parte fissa:

  describe('OnePiece', () => {
      test('fetches the data from the API and correctly renders it', async () => {
          render(<OnePiece />)
          setTimeout(async () => {
              const items = await screen.findAllByAltText('product-image');
              expect(items).toHaveLength(2);
            }, 4000)
            //screen.debug()
        })
    })
2021-11-23 19:55:14

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................