I'm trying to test the component below using mock axios, however, it looks like the components are not rendered as expected, could someone help me on that? I have been stuck for quite a while. The component is fetching an api every 1 second.
const RealtimePrice = () => {
var [cryptoFeed, setCryptoFeed] = useState<cryptoFeed>([]);
var [currency, setCurrency] = useState(currencyList[0]);
var [cryptoSearch, setCryptoSearch] = useState("");
const url = `https://api.coingecko.com/api/v3/coins/markets?ids=${ids}&vs_currency=${currency}`;
const intervalRef = useRef<NodeJS.Timer>();
const onCurrencyChangeHandler = useCallback((newValue: string) => {
setCurrency(newValue);
}, []);
const onCryptoSearchChangeHandler = useCallback((newValue: string) => {
setCryptoSearch(newValue);
}, []);
useEffect(() => {
const getCryptoFeed = () => {
axios.get(url).then((response: any) => {
if (response.data) {
console.debug("The state is set");
setCryptoFeed(response.data);
} else {
console.debug("The state is not set");
setCryptoFeed([]);
}
});
};
getCryptoFeed();
intervalRef.current = setInterval(getCryptoFeed, 1000);
return () => {
clearInterval(intervalRef.current);
};
}, [url]);
const priceBlocks = cryptoFeed
.filter((crypto) =>
crypto.name.toLowerCase().includes(cryptoSearch.toLowerCase())
)
.map((crypto: any) => {
return (
<PriceBlock
key={crypto.id}
id={crypto.id}
name={crypto.name}
price={crypto.current_price}
volume={crypto.total_volume}
change={crypto.price_change_24h}
></PriceBlock>
);
});
return (
<div className={styles.container}>
<div className={styles["header-section"]}>
<h1>Cryptocurrency Realtime Price</h1>
<div className="input-group">
<Selectbox
onChange={onCurrencyChangeHandler}
defaultOption={currencyList[0]}
options={currencyList}
/>
<Inputbox
placeHolder="Enter crypto name"
onChange={onCryptoSearchChangeHandler}
/>
</div>
</div>
<div className={styles.priceblocks}>{priceBlocks}</div>
</div>
);
};
The test is the defined as the following, findByText gives error, it couldn't find the element.
import { render, screen } from "@testing-library/react";
import RealtimePrice from "../RealtimePrice";
describe("Realtime Price", () => {
it("should render the Bitcoin price block", async () => {
render(<RealtimePrice />);
const pb = await screen.findByText("Bitcoin");
expect(pb).toBeInTheDocument();
});
});
And in package.json I have set
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}"
],
"resetMocks": false
}
In src/mocks/axios.js
const mockGetResponse = [
{
id: "bitcoin",
name: "Bitcoin",
price: 20000,
volume: 12004041094,
change: -12241,
},
{
id: "solana",
name: "Solana",
price: 87,
volume: 200876648,
change: 122,
},
];
const mockResponse = {
get: jest.fn().mockResolvedValue(mockGetResponse),
};
export default mockResponse;
CodePudding user response:
With our comments seems clear the issue is that mock is not returning a proper response.data (that's why u are setting an empty array as the state)
Try doing:
const mockResponse = {
get: jest.fn().mockResolvedValue({data: mockGetResponse}),
};