* react-router-dom 설치
GET http://localhost:8080/test/main.js net::ERR_ABORTED 404 (Not Found) 오류 해결
클릭시 랜더링되지만 주소창에 url통해서는 안들어가지는 오류 발생
>>해결:
▼ 과제 제출 코드 참고
App.jsx
import {
Routes,
Route,
Link,
} from 'react-router-dom';
import HomePage from './HomePage';
import AboutPage from './AboutPage';
import RestaurantsPage from './RestaurantsPage';
import RestaurantsInfoPage from './RestaurantsInfoPage';
import NotFoundPage from './NotFoundPage';
export default function App() {
return (
<div>
<header>
<h1>
<Link to="/">헤더 영역</Link>
</h1>
</header>
<Routes>
<Route exact path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
<Route path="/restaurants" element={<RestaurantsPage />} />
<Route path="/restaurants/:id" element={<RestaurantsInfoPage />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</div>
);
}
App.test.jsx
import { MemoryRouter } from 'react-router-dom';
import { render } from '@testing-library/react';
import { useDispatch, useSelector } from 'react-redux';
import App from './App';
import restaurants from '../fixtures/restaurants';
import categories from '../fixtures/categories';
import regions from '../fixtures/regions';
describe('App', () => {
beforeEach(() => {
const dispatch = jest.fn();
useDispatch.mockImplementation(() => dispatch);
useSelector.mockImplementation((selector) => selector({
regions,
categories,
restaurants,
}));
});
const renderApp = ({ path }) => render((
<MemoryRouter initialEntries={[path]}>
<App />
</MemoryRouter>
));
context('올바른 경로일 경우', () => {
it('"/"일 때, HomePage가 랜더링된다', () => {
const { container } = renderApp({ path: '/' });
expect(container).toHaveTextContent('HomePage');
});
it('"/about"일 때, AboutPage가 랜더링된다', () => {
const { container } = renderApp({ path: '/about' });
expect(container).toHaveTextContent('About 페이지입니다.');
});
it('"/restaurants"일 때, RestaurantsPage가 랜더링된다', () => {
const { container } = renderApp({ path: '/restaurants' });
expect(container).toHaveTextContent('김밥제국');
});
});
context('잘못된 경로일 경우', () => {
it('NotFoundPage가 랜더링된다', () => {
const { container } = renderApp({ path: '/xxx' });
expect(container).toHaveTextContent('404 Not Found Page');
});
});
});
actions.test.jsx
import thunk from 'redux-thunk';
import configureStore from 'redux-mock-store';
import restaurantInfo from '../fixtures/restaurantInfo';
import {
loadInitialData,
setRegions,
setCategories,
loadRestaurants,
setRestaurants,
loadRestaurantsInfo,
setRestaurantInfo,
} from './actions';
const middlewares = [thunk];
const mockStore = configureStore(middlewares);
jest.mock('./services/api');
describe('actions', () => {
let store;
describe('loadInitialData', () => {
beforeEach(() => {
store = mockStore({});
});
it('runs setRegions and setCategories', async () => {
await store.dispatch(loadInitialData());
const actions = store.getActions();
expect(actions[0]).toEqual(setRegions([]));
expect(actions[1]).toEqual(setCategories([]));
});
});
describe('loadRestaurants', () => {
context('with selectedRegion and selectedCategory', () => {
beforeEach(() => {
store = mockStore({
selectedRegion: { id: 1, name: '서울' },
selectedCategory: { id: 1, name: '한식' },
});
});
it('runs setRestaurants', async () => {
await store.dispatch(loadRestaurants());
const actions = store.getActions();
expect(actions[0]).toEqual(setRestaurants([]));
});
});
context('without selectedRegion', () => {
beforeEach(() => {
store = mockStore({
selectedCategory: { id: 1, name: '한식' },
});
});
it('does\'nt run any actions', async () => {
await store.dispatch(loadRestaurants());
const actions = store.getActions();
expect(actions).toHaveLength(0);
});
});
context('without selectedCategory', () => {
beforeEach(() => {
store = mockStore({
selectedRegion: { id: 1, name: '서울' },
});
});
it('does\'nt run any actions', async () => {
await store.dispatch(loadRestaurants());
const actions = store.getActions();
expect(actions).toHaveLength(0);
});
});
});
describe('loadRestaurantsInfo', () => {
beforeEach(() => {
store = mockStore({
restaurantInfo,
});
});
it('setRestaurantInfo를 실행한다', async () => {
await store.dispatch(loadRestaurantsInfo());
const actions = store.getActions();
expect(actions[0]).toEqual(setRestaurantInfo([]));
});
});
});
webpack.config.js는 아래로도 사용 가능
'CodeSoom- React 13기' 카테고리의 다른 글
[코드숨] 리액트 13기 -8강/1.Emotion(CSS-in-JS라이브러리) (0) | 2022.12.03 |
---|---|
[코드숨] 리액트 13기 -7강/로그인(HTTPie,Authorization 헤더,LocalStorage,given, 리뷰) (0) | 2022.11.27 |
[코드숨] 리액트 13기 -6강/라우팅(Routing) (0) | 2022.11.18 |
[코드숨] 리액트 13기 -5강/과제1(레스토랑 조회 구현하기) 풀이 참고 (0) | 2022.11.13 |
[코드숨] 리액트 13기 -5강/과제1:레스토랑 조회 구현하기 오류 (0) | 2022.11.11 |