Next.jsのページコンポーネント内の関数をJestを使用してテストした際のエラー
解決したいこと
Next.jsのデータ層にfirestore 認証にFirebase Authenticationを使用したTODOアプリケーション
でJestを使用して関数の呼び出しをテストしたいです。
モック化等はうまくいってると思いますが、下記エラーが出ています。
解決方法を教えてください。
テストしたい関数
・handleLoginButton, handleLogoutButton, addTodo, editTodo, deleteTodo
発生している問題・エラー
ReferenceError: handleLoginButton is not defined
143 | };
144 |
> 145 | module.exports = { handleLoginButton, handleLogoutButton, addTodo, editTodo, deleteTodo };
該当するソースコード
index.jsx(ページコンポーネント)
import {
addDoc,
collection,
deleteDoc,
doc,
getDocs,
setDoc,
} from "firebase/firestore";
import { useState } from "react";
import { useAuth } from "../components/AuthContext";
import { db } from "../firebase";
import { dbAdmin } from "../firebaseAdmin";
export default function Index(props) {
const { currentUser, login, logout } = useAuth();
const [input, setInput] = useState("");
const [updateTodo, setUpdateTodo] = useState([{ id: "", todo: "" }]);
const handleLoginButton = () => {
login();
};
const handleLogoutButton = () => {
logout();
};
const addTodo = async () => {
await addDoc(collection(db, "todos"), { todo: input });
setInput("");
};
const editTodo = async (id) => {
await setDoc(doc(db, "todos", id), { todo: updateTodo });
setUpdateTodo("");
};
const deleteTodo = async (id) => {
await deleteDoc(doc(db, "todos", id));
};
return (
<>
<h2 style={{ textAlign: "center" }}>TODOアプリケーション</h2>
{currentUser && (
<>
<div style={{ textAlign: "right", marginRight: "40px" }}>
<h3>ログイン中</h3>
<button onClick={handleLogoutButton}>ログアウト</button>
</div>
<div style={{ display: "flex", justifyContent: "center" }}>
<input
value={input}
onChange={(e) => {
setInput(e.target.value);
}}
/>
<button onClick={addTodo}>登録</button>
</div>
<h2 style={{ textAlign: "center", borderBottom: "solid" }}>
TODO一覧
</h2>
<ul
style={{
marginLeft: "620px",
display: "inline-block",
marginTop: "5px",
}}
>
{props.todos.map((todo) => {
return (
<div
key={todo.id}
style={{
display: "flex",
marginBottom: "10px",
}}
>
<li style={{ fontSize: "20px" }}>
{todo.todo}
</li>
<input
value={updateTodo.todo}
style={{ marginLeft: "10px" }}
onChange={(e) => {
setUpdateTodo(e.target.value);
}}
></input>
<button
onClick={() => {
editTodo(todo.id);
}}
>
更新
</button>
<button
onClick={() => {
deleteTodo(todo.id);
}}
>
削除
</button>
</div>
);
})}
</ul>
</>
)}
{!currentUser && (
<>
<div style={{ textAlign: "center" }}>
<h2>ログインしていません。</h2>
<button onClick={handleLoginButton}>ログイン</button>
</div>
</>
)}
</>
);
}
export const getServerSideProps = async () => {
try {
const col = dbAdmin.collection("todos");
const snap = await col.get();
const todos = snap.docs.map((todo) => {
return {
id: todo.id,
todo: todo.data().todo,
};
});
console.log(todos);
return {
props: { todos },
};
} catch (error) {
console.log(error);
const todos = { id: "", todo: "" };
return {
props: { todos },
};
}
};
module.exports = { handleLoginButton, handleLogoutButton, addTodo, editTodo, deleteTodo };
index.test.js
import { handleLoginButton, handleLogoutButton, addTodo, editTodo, deleteTodo } from "../pages/index";
jest.mock("firebase/firestore", () => ({
addDoc: jest.fn(() => Promise.resolve()),
collection: jest.fn(),
deleteDoc: jest.fn(() => Promise.resolve()),
doc: jest.fn(),
setDoc: jest.fn(() => Promise.resolve())
}));
jest.mock("../components/AuthContext", () => ({
useAuth: jest.fn(() => ({
currentUser: {},
login: jest.fn(),
logout: jest.fn()
}))
}));
jest.mock("../firebase", () => ({
db: {}
}));
jest.mock("../firebaseAdmin", () => ({
dbAdmin: {
collection: jest.fn(() => ({
get: jest.fn(() => ({
docs: [{
id: "1",
data: jest.fn(() => ({
todo: "test todo"
}))
}]
}))
}))
}
}));
describe("Index", () => {
it("handleLoginButton should call login", () => {
const { handleLoginButton } = require("../pages/index");
handleLoginButton();
expect(useAuth().login).toHaveBeenCalled();
});
it("handleLogoutButton should call logout", () => {
const { handleLogoutButton } = require("../pages/index");
handleLogoutButton();
expect(useAuth().logout).toHaveBeenCalled();
});
it("addTodo should call addDoc", async () => {
const { addTodo } = require("../pages/index");
await addTodo();
expect(addDoc).toHaveBeenCalled();
});
it("editTodo should call setDoc", async () => {
const { editTodo } = require("../pages/index");
await editTodo("1");
expect(setDoc).toHaveBeenCalled();
});
it("deleteTodo should call deleteDoc", async () => {
const { deleteTodo } = require("../pages/index");
await deleteTodo("1");
expect(deleteDoc).toHaveBeenCalled();
});
});
自分で試したこと
関数名の確認等は何度も行いました。
Jestについてはほぼ初なので宜しくお願いします。
0 likes