when user type some text in input search data-testid = 'loading' must be removed, now console return Unable to find an element by: [data-testid="loading"] can some one sugesstion me to writting test with swr or suggestion for me how to mock response from swr
this is my component file
import axios from "axios";
import { useEffect, useState } from "react";
import useSWR from "swr";
import "./styles.css";
const useDebounce = (newValue) => {
const [value, setValue] = useState("");
useEffect(() => {
const timeout = setTimeout(() => {
setValue(newValue);
}, 500);
return () => clearTimeout(timeout);
}, [newValue]);
return value;
};
export const fetcher = async (url) => {
const { data } = await axios.get(url);
return data;
};
export default function App() {
const [query, setQuery] = useState("react");
const searchQuery = useDebounce(query);
const { data: repos } = useSWR(
`https://api.github.com/search/repositories?q=${searchQuery}&per_page=1&page=1`,
fetcher
);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<input
testId="search"
data-testid="search"
id="search-input"
placeholder="search"
onChange={(event) => setQuery(event.target.value)}
/>
{!repos ? (
<div data-testid="loader" testId="loader">
<h2 id="loading">loading</h2>
</div>
) : (
repos?.items?.map((user) => {
return (
<div
data-testid="repo-item"
style={{
margin: "1rem",
height: "40px",
background: "lightpink"
}}
>
{user.name}
</div>
);
})
)}
</div>
);
}
this is my test file
import {
render,
screen,
waitForElementToBeRemoved
} from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import App from "./App";
import { act } from "react-dom/test-utils";
describe("test", () => {
beforeEach(() => {
jest.resetAllMocks();
jest.useFakeTimers();
});
it("happy render", () => {
expect(() => render(<App />)).not.toThrow();
});
it("renders after search", async () => {
render(<App />);
userEvent.type(screen.getByTestId("search"), "vue");
act(() => {
jest.runAllTimers();
});
await waitForElementToBeRemoved(() => screen.getByTestId("loader"));
});
});
You can mock axios.get()
method and its resolved/rejected value rather than mocking useSWR
hook. Then, test the behaviour of the component such as what was rendered when data was returned, and what was rendered when no data was available.
E.g.
App.tsx
:
import axios from 'axios';
import React from 'react';
import { useEffect, useState } from 'react';
import useSWR from 'swr';
const useDebounce = (newValue) => {
const [value, setValue] = useState('');
useEffect(() => {
const timeout = setTimeout(() => {
setValue(newValue);
}, 500);
return () => clearTimeout(timeout);
}, [newValue]);
return value;
};
export const fetcher = async (url) => {
const { data } = await axios.get(url);
return data;
};
export default function App() {
const [query, setQuery] = useState('react');
const searchQuery = useDebounce(query);
const { data: repos } = useSWR(
`https://api.github.com/search/repositories?q=${searchQuery}&per_page=1&page=1`,
fetcher
);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<input
data-testid="search"
id="search-input"
placeholder="search"
onChange={(event) => setQuery(event.target.value)}
/>
{!repos ? (
<div data-testid="loader">
<h2 id="loading">loading</h2>
</div>
) : (
repos?.items?.map((user) => {
console.log('user: ', user);
return (
<div key={user.id} data-testid="repo-item">
{user.name}
</div>
);
})
)}
</div>
);
}
App.test.tsx
:
import React from 'react';
import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import App from './App';
import { act } from 'react-dom/test-utils';
import axios from 'axios';
describe('test', () => {
beforeEach(() => {
jest.clearAllMocks();
jest.useFakeTimers();
});
it('happy render', () => {
expect(() => render(<App />)).not.toThrow();
});
it('renders after search', async () => {
jest.spyOn(axios, 'get').mockResolvedValueOnce({
data: {
items: [
{ id: 1, name: 'react' },
{ id: 2, name: 'jestjs' },
],
},
});
render(<App />);
userEvent.type(screen.getByTestId('search'), 'vue');
act(() => {
jest.runAllTimers();
});
await waitForElementToBeRemoved(() => screen.getByTestId('loader'));
});
});
test result:
PASS examples/67958776/App.test.tsx (8.166 s)
test
✓ happy render (42 ms)
✓ renders after search (58 ms)
console.log
user: { id: 1, name: 'react' }
at examples/67958776/App.tsx:45:19
at Array.map (<anonymous>)
console.log
user: { id: 2, name: 'jestjs' }
at examples/67958776/App.tsx:45:19
at Array.map (<anonymous>)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 80 | 100 | 100 |
App.tsx | 100 | 80 | 100 | 100 | 44
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 8.873 s
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With