μ 무λ₯Ό 보면μ νμ¬ μ§ν μ€μΈ νλ‘μ νΈμ μ½λλ₯Ό μ‘°κΈ λ κ°μ μν€κ³ μμΌλ‘μ μμ μ νΈνκ² κ°μ Έκ°κΈ° μν΄μ μ΄λ€ μΌλ€μ ν μ μμκΉ? νλ μκ°μ νλ€κ° ν μ€νΈ μ½λ μ ν μ ν΄λ³΄μλΌλ λ€μ§μ νκ² λμλ€. νμ¬ μ§ν μ€μΈ μ½λμμλ ν μ μκΈ° λλ¬Έμ λΉμ·ν νκ²½μ μ‘°μ±ν ν μ€νΈ μ½λλ₯Ό κ°μ§κ³ μν μΌμμ ν μ€νΈ κ°λ°νκ²½μ μ‘°μ±νλ €κ³ μλνλ€. μ¬κ±Έ? μ½μ§μ μ΄ν μ¬ν λμ νκ³ λλλ€. νμ§λ§ μ¬μ ν λ―ΈκΆμ λΉ μ Έμκ³ μ΄κ±Έ λ€μ μ¬μ°ν΄λΌ μ μμκΉ? νλ μλ¬Έμ΄ κ°νκ² λ€μ΄μ λ€κΈνκ² μ΄κ³³μ λ¨κ²¨λ³΄λ €κ³ νλ€.
맨λ λ£κΈ°λ§νκ³ μ¬κΈ°μ κΈ° ꡬκΈλ§ νλ€κ° λ³΄κΈ°λ§ νμ§. μ μ μ¨λ³Έ μ μ μλ ν μ€νΈ μ½λ. μ¬λ¬ λΈλ‘κ·Έλ₯Ό μ°Έκ³ ν΄μ μ§νμ νμλλ°, λνλ μ λλ‘ μ΄ν΄νλ κ² μμΌλ μ½λλ μμ 짬λ½μ΄ λκ³ testλ λμ§λ μκ³ κ·Έλμ μ λͺ¨λ₯΄κ² μΌλ©΄ λλ€? 곡μλ¬Έμλ₯Ό 보μ.
- Quick Start λΆν° 보μλ©΄ λ©λλ€! μ²μ²ν μ½μ΄λ³΄μκ³ μ°¨κ·Όμ°¨κ·Ό μλν΄λ³΄λ©΄ λλ€. λΉμ°ν 머리μμλ μ₯κ° λ κ²μ΄λ€.
μ¬κΈ°μ μμν΄μ μ€λ₯κ° λλ€λ©΄ κ·Έ μ€λ₯λ€μ νλνλμ© ν€μ³λκ°μλΌκ³ μκ°νλ€. μ½μ§ μλ€.
νμν ν¨ν€μ§ μ€μΉνκΈ°
μμ² λ§μ ν¨ν€μ§λ€μ΄ νμνλ€. μΌλ¨ jestλ₯Ό nextjs μ μ¬μ©νκΈ° μν κ²λ νμνκ³ typescript μλ μ»΄νμΌμ΄ λμ΄μΌ νκΈ° λλ¬Έμ κ·Έμ λν μ°κ΄ ν¨ν€μ§λ€λ μ€μΉν΄μ€μΌ νλ€.
npm install @testing-library/dom @testing-library/jest-dom @testing-library/react
@testing-library/user-event babel-jest jest jest-dom ts-jest ts-loader
βοΈ λ¦¬μ‘νΈ μ»΄ν¬λνΈλ₯Ό κ°μ λΈλΌμ°μ μμ ν μ€νΈνκΈ° μν κΈ°λ₯μ μ 곡νλ @testing-library ν¨ν€μ§λ€,
βοΈ babel-jestλ ν μ€νΈ μ½λλ₯Ό λ³ννκ³ μ»΄νμΌνλ€.
βοΈ ts-jest, ts-loader λ Jestμμ νμ μ€ν¬λ¦½νΈ κΈ°λ°μ μ½λλ₯Ό ν μ€νΈν μ μκ² ν΄ μ€λ€.
% API routes ν μ€νΈλ₯Ό μν΄μλ node-mocks-http λΌλ κ²λ μ€μΉ. μμ§ μ κ·Έ λ¨κ³κΉμ§ λͺ»ν΄μ μ°μ μμ μ λλ§ ν΄λμ μν©. node-mocks-httpλ Next API routesλ₯Ό ν μ€νΈν λ νμν request, response κ°μ²΄μ mockμ μμ±ν΄ μ€λ€.
μΆκ°ν΄μΌ ν μ€μ νμΌλ€
- tsconfig.json
CNAμ νμ μ€ν¬λ¦½νΈλ₯Ό λν΄μ μ¬μ©νλ€λ©΄ μ΄λ―Έ μμ±λμ΄μμ νμΌλ‘ pathλΌλ κ°λ§ λν΄μ£Όλ©΄ λλ€. ν μ€νΈ μ½λ μ μ μμ pathλ₯Ό μΌμΌμ΄ μ μ§ μμλ import ν μ μκ² ν΄ μ€λ€.
{
"compilerOptions" : {
.....
"path" : {
'@components/*': ["components/*"],
"@pages/*": ["pages/*"],
"@styles/*":["hooks/*"]
}
}
}
- jest.config.json
곡μλ¬Έμμ 보μλ©΄ λν΄νΈλ‘ λμμλ νμ. νμ§λ§ css import κ°μ κ²½μ°μ mocksκ° μλ€λ©΄ μ§μ°κ³ , cssλ νμνμλ©΄ ν΄λ λ§λ€κ³ νμΌ λ§λ€μ΄μ μ°λ©΄ λλ€. λλ νμ μμ΄μ μΉ μ§μλ΄κ³ , pageμ componentsλ§ λ¨κ²Όλ€
// jest.config.json
module.exports = {
collectCoverageFrom: [
"**/*.{js,jsx,ts,tsx}",
"!**/*.d.ts",
"!**/node_modules/**"
],
moduleNameMapper: {
// Handle CSS imports (with CSS modules)
// https://jestjs.io/docs/webpack#mocking-css-modules
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy",
// Handle CSS imports (without CSS modules)
"^.+\\.(css|sass|scss)$": "<rootDir>/styles/__mocks__/styleMock.js",
// Handle image imports
// https://jestjs.io/docs/webpack#handling-static-assets
"^.+\\.(jpg|jpeg|png|gif|webp|avif|svg)$": `<rootDir>/__mocks__/fileMock.js`,
// Handle module aliases
"^@pages/(.*)$": "<rootDir>/pages/$1",
"^@components/(.*)$": "<rootDir>/components/$1"
},
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
testPathIgnorePatterns: ["<rootDir>/node_modules/", "<rootDir>/.next/"],
testEnvironment: "jsdom",
transform: {
// Use babel-jest to transpile tests with the next/babel preset
// https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
"^.+\\.(js|jsx|ts|tsx)$": ["babel-jest", { presets: ["next/babel"] }]
},
transformIgnorePatterns: ["/node_modules/", "^.+\\.module\\.(css|sass|scss)$"]
};
- jest.setup.js
μμ μλ νλͺ© μ€μ μ΄ νμΌμ μ μ κ³³μ΄ μμ΅λλ€. ν μ€νΈ μ€ννκΈ° μ μ λ°λμ μΈν ν΄μΌ νλ νμΌμ λλ€. μμλ 곡μλ¬Έμμμ νμΈν μ μλ€. ν¬κ² ν κ² μκ³ , importλ§ ν΄μ£Όλ©΄ μ€ν€λν€
import '@testing-library/jest-dom/extend-expect'
- package.json
"test" : "jest"
ν μ€νΈνκΈ°
ν μ€νΈλ₯Ό μν ν΄λλ₯Ό νλ λ§λ€μ΄μ£Όμ!
__test__ ν΄λ μμ api , components, page λ± λ ν΄λλ₯Ό λλ λ λκ³ κ·Έλ₯ ν μ€νΈνκ³ μΆμ νμΌμ λ°λ‘ μ¨λ λλ€.
μμλ ν μ€νΈ μ½λ μμ±μ λν λΆλΆλ 곡μλ¬Έμμμ λ³Ό μ μλ€. μ¬κΈ°μλ μ ν΄μ§ λ£°μ΄ μμ΄μ μ¬μ€ ν μ€νΈ μ½λλ₯Ό μμ±νλ κ²λ μΌμ΄λ€. μ΅μν΄μ§κΈ°κ° μ½μ§ μλ€. λ μμ λ¨μν νΉμ νμΌμ ν μ€νΈκ° μλμ§λ₯Ό νμΈν΄μ£Όλ ν μ€νΈ μ½λλ₯Ό μΌλ€.
// __test__/index.test.tsx
import { render, screen } from "@testing-library/react";
import Home from "@pages/index";
describe('Home', () => {
it("render some text", () => {
const { container } = render(<Home />);
const home = screen.getByText('Home');
expect(home).toBeInTheDocument();
expect(container).toMatchSnapshot();
});
});
ν μ€νΈ μ½λλ₯Ό λ€ μμ±νλ€λ©΄? ν°λ―Έλμ μ μ΄λ³΄μ!
npm test
"μ΄?!" κΈμ§μΈ κ°λ°μ μ¬λ¬΄μ€μμ "μ΄!!!!!!!!"λ₯Ό μΈμΉκ² ν μκ°
μ΄λ κ² passκ° λκΈ°κΉμ§ λ§μ μκ°μ΄ κ±Έλ Έλ€. κ·Έλμ ν μ€νΈ μ½λμ λν΄ λ§μ κΈλ€μ μ½μλ€. μ½μΌλ©΄μ μ λ ν μ€νΈλΌκ³ νλ©΄ μ΄λκΉμ§μΈκ°μ νμ μμ μ΄λκΉμ§ μ΄λ»κ² ν μ€νΈν΄μΌ νλ κ±ΈκΉ?λΌλ μκ°μ΄ λ€μλ€. λ¨μνκ² λ²νΌ λ‘λ©λλ κ²λ§μΌλ‘ ν μ€νΈνλ€κ³ ν μ μμκΉ? μ λ ν μ€νΈλΌλ κ² μ λ§ κ·Έλ° λΈλΌμ°μ νκ²½μ μμ λ¨μλ₯Ό λ§νλ κ²μΈκ°? κ·Έκ²μ μλλ€. λΉλΉνκ² μ΄λ° ν μ€νΈ μ½λλ₯Ό μμ±ν΄λ³΄μκ³ μ μνκ³ μΆμλλ° μ΄λκΉμ§ ν μ€νΈλ₯Ό μ§νν΄μΌ νλ κ°μ λν μλ¬Έκ³Ό λ λ€λ₯Έ λ―Έν μ κ°μ Έμ¬ κ² κ°μ μκ°μ μ£ΌμΆ€λλ€.
μ°Έκ³ μλ£λ€
μ€μΉλΆν° - pass λ°κΈ° μ κΉμ§ νλνλ μ€λ₯λ€μ λ§λμ serching νλ κΈ°λ‘λ€μ΄λ€
- https://stackoverflow.com/questions/71713405/cannot-find-module-react-dom-client-from-node-modules-testing-library-react
- https://yoonho-devlog.tistory.com/177
- https://yeoulcoding.me/244
- https://yoonho-devlog.tistory.com/175
'κ°λ° > Next.js' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
Next.js14μμ useRouter μ¬μ©νκΈ° (1) | 2024.01.03 |
---|---|
NEXT.js14 API Routes μ¬μ©νκΈ° (with. MONGODB) (1) | 2024.01.03 |
npm start, npm run dev μ μ°¨μ΄μ (1) | 2023.12.29 |
[Next.js (SSG) /cloudFront] λ°°ν¬ μ΄ν reloadμμ dynamic routeλ₯Ό λͺ» ν λ ν΄κ²° (0) | 2023.08.07 |
[NextJS] SSR 곡λΆνκΈ° (Static Generation vs Server-side Rendering) (0) | 2022.06.07 |