test(web): starter unit tests for service, header, bottom#76
Merged
Conversation
Three small specs covering the most reachable surfaces:
- src/api/service.spec.ts — mocks axios at the module boundary
(require pattern instead of ES import so axios.create is stubbed
before service.ts evaluates), asserts the proxy baseURL and that
getAPI forwards path + props as query params and unwraps the
response data.
- src/components/header.spec.tsx — mocks next/navigation,
front/hooks (useSido), and front/site/home/Count (CountList) so
Header can render in isolation; asserts the title link renders
and clicking it calls router.push('/').
- src/components/bottom.spec.tsx — mocks next/navigation
(useRouter + usePathname) and asserts the three nav items render
with their aria labels, that clicking '조회하기' fires
router.push('/search'), and that the active item picks up the
text-primary class when usePathname matches.
The placeholder app/providers.spec.tsx from #30 stays.
- nx test web: 4 suites, 9 tests, all pass
- nx affected -t lint test build green (5 projects)
Reviewer's GuideAdds initial Jest/React Testing Library unit tests for the web app’s API service wrapper and Header/Bottom layout components, using targeted mocking of external dependencies to verify routing, rendering, and axios configuration/behavior. Sequence diagram for getAPI axios mocking and call behaviorsequenceDiagram
participant Jest
participant axiosModule as axios
participant serviceSpec as service_spec
participant serviceModule as service
participant axiosInstance
Jest->>axiosModule: jest.mock(axios)
Jest->>axiosModule: (axios.create as jest.Mock).mockReturnValue({ get: mockGet })
serviceSpec->>serviceModule: require(service)
activate serviceModule
serviceModule->>axiosModule: axios.create({ baseURL: /api/data-go-kr, timeout: 10000 })
axiosModule-->>serviceModule: axiosInstance
deactivate serviceModule
serviceSpec->>serviceModule: getAPI({ pageNo: 1, numOfRows: 10 }, /sido_v2)
serviceModule->>axiosInstance: get(/sido_v2, { params: { pageNo: 1, numOfRows: 10 } })
axiosInstance-->>serviceModule: { data: { foo: bar } }
serviceModule-->>serviceSpec: { foo: bar }
serviceSpec->>serviceModule: getAPI({}, /kind_v2)
serviceModule->>axiosInstance: get(/kind_v2, { params: {} })
axiosInstance-->>serviceModule: { data: { count: 42 } }
serviceModule-->>serviceSpec: { count: 42 }
Sequence diagram for Header component navigation testsequenceDiagram
actor Tester
participant Jest
participant useRouterHook as useRouter
participant useSidoHook as useSido
participant CountListComponent as CountList
participant HeaderComponent as Header
Jest->>useRouterHook: mockImplementation(() => { push: mockPush })
Jest->>useSidoHook: mockImplementation(() => mockedSidoState)
Jest->>CountListComponent: mockImplementation(() => <div>mocked_count_list</div>)
Tester->>HeaderComponent: render(<Header />)
HeaderComponent->>useRouterHook: useRouter()
useRouterHook-->>HeaderComponent: { push: mockPush }
HeaderComponent->>useSidoHook: useSido()
useSidoHook-->>HeaderComponent: mockedSidoState
HeaderComponent->>CountListComponent: render CountList
Tester->>HeaderComponent: find title link
Tester->>HeaderComponent: userEvent.click(title_link)
HeaderComponent->>useRouterHook: push(/)
useRouterHook-->>HeaderComponent: void
Jest->>useRouterHook: expect(mockPush).toHaveBeenCalledWith(/)
Sequence diagram for Bottom nav routing and active state testssequenceDiagram
actor Tester
participant Jest
participant useRouterHook as useRouter
participant usePathnameHook as usePathname
participant BottomComponent as Bottom
Jest->>useRouterHook: mockImplementation(() => { push: mockPush })
Jest->>usePathnameHook: mockImplementation(() => /search)
Tester->>BottomComponent: render(<Bottom />)
BottomComponent->>useRouterHook: useRouter()
useRouterHook-->>BottomComponent: { push: mockPush }
BottomComponent->>usePathnameHook: usePathname()
usePathnameHook-->>BottomComponent: /search
BottomComponent-->>Tester: three nav items with aria labels
Tester->>BottomComponent: userEvent.click(nav_item_조회하기)
BottomComponent->>useRouterHook: push(/search)
useRouterHook-->>BottomComponent: void
Jest->>useRouterHook: expect(mockPush).toHaveBeenCalledWith(/search)
BottomComponent-->>Tester: nav_item_matching_/search has class text-primary
Jest->>BottomComponent: expect(active_item).toHaveClass(text-primary)
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In
service.spec.ts, consider switching fromrequire+eslint-disable no-var-requiresto animportwith ajest.mock('axios', () => ({ create: jest.fn() }))factory so the test aligns with the ESM/TypeScript style and avoids global eslint disables while still letting you control theaxios.createinstance initialization order.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `service.spec.ts`, consider switching from `require` + `eslint-disable no-var-requires` to an `import` with a `jest.mock('axios', () => ({ create: jest.fn() }))` factory so the test aligns with the ESM/TypeScript style and avoids global eslint disables while still letting you control the `axios.create` instance initialization order.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
View your CI Pipeline Execution ↗ for commit 38a3ba6
☁️ Nx Cloud last updated this comment at |
… specs The import/first ESLint rule rejects `import` statements that appear after `jest.mock` calls — but jest.mock must precede the imports under test for the hoisting + factory contract to work. Inline-disable the rule on the affected import lines.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three small specs covering the most reachable surfaces. The placeholder
app/providers.spec.tsxfrom #30 stays.src/api/service.spec.tsMocks axios at the module boundary (
requirepattern instead of ES import soaxios.createis stubbed beforeservice.tsevaluates). Asserts:baseURL: '/api/data-go-kr'getAPIforwards path + props as query paramssrc/components/header.spec.tsxMocks
next/navigation,front/hooks(useSido), andfront/site/home/Count(CountList) soHeadercan render in isolation. Asserts:router.push('/')src/components/bottom.spec.tsxMocks
next/navigation(useRouter+usePathname). Asserts:router.push('/search')text-primaryclass whenusePathnamematchesTest plan
npx nx test web: 4 suites, 9 tests, all passnpx nx affected -t lint test buildgreen (5 projects)🤖 Generated with Claude Code
Summary by Sourcery
Add initial unit test coverage for the web app service API wrapper and key navigation components.
Tests: