So I am testing a component that uses a custom hook I made called "useFetch". I tried mocking useFetch for the component and then the .map call in my component is giving me the error: Error: Uncaught [TypeError: Cannot read property 'map' of undefined]
This is my first time writing tests for my project, so I'm sure there's something I'm doing wrong here and not sure how to proceed. Is there anyway to pass the initial rendering of my component?
useFetch.js
import React, { useState, useEffect } from 'react';
import { useAuth } from '../context/AuthContext';
import firebase from '../firebase'
const useFetch = () => {
const [timerData, setTimerData] = useState({
error: null,
loading: true,
timerList: []
});
const { getUuid } = useAuth();
useEffect(() => {
const unsubscribe = firebase
.firestore()
.collection('users')
.doc(getUuid())
.collection('timers')
.onSnapshot((snapshot) => {
const newTimers = snapshot.docs.map((doc) => ({
...doc.data(),
id: doc.id
}))
newTimers.sort(function (x, y) {
return x.timerHistory[0].timeStamp - y.timerHistory[0].timeStamp;
})
setTimerData({
error: null,
loading: false,
timerList: newTimers
},
(error) => {
setTimerData({
error,
loading: false,
timerList: []
})
}
)
})
return () => unsubscribe();
}, [])
return timerData;
}
export default useFetch;
Component I'm testing: TimerList.js
import ToggleableTimerForm from "./ToggleableTimerForm";
import TimerController from "./TimerController";
import useFetch from "../../hooks/useFetch";
const TimerList = () => {
const { error, loading, timerList } = useFetch();
return (
<div className="timerlist column">
<ul className="row timerGrid">
{timerList.map(timer => {
return (<TimerController timer={timer} key={timer.id} />)
})}
<ToggleableTimerForm />
</ul>
</div>
);
}
export default TimerList;
My test: TimerList.test.js
import React from "react";
import TimerList from "../TimerList";
import { render, fireEvent, screen, cleanup } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
jest.mock("../../../hooks/useFetch", () => ({
__esModule: true,
default: () => ({
timerData: {
error: null,
loading: true,
timerList: [{
id: "fakeid",
name: "timer1"
}]
}
}),
}));
jest.mock('../../../firebase', () => ({
firebase: {
firestore: jest.fn(() => ({})),
},
}));
describe('<TimerList />', () => {
it('renders the initial <TimerList />', () => {
const { queryByTestId } = render(
<TimerList />
);
});
});
Edit: Solved this problem by changing the shape of my mock as per tromgy's advice.
jest.mock("../../../hooks/useFetch", () => ({
__esModule: true,
default: () => ({
error: "",
loading: false,
timerList: []
}),
}));