본문 바로가기

TIL(Today i learned)

[TIL-2022.10.23] Nextjs에서 라우팅 테스트하기

1.next관련 좋은 영상을 찾았다 : 

 

유튜브에서 next router test 관련 영상을 찾아보다가, 성능 최적화 관련된 영상도 발견했다. 그래서 그냥 여기에 저장해두려고 한다. 

https://youtu.be/hZr4J42JDoc

https://www.youtube.com/watch?v=TOP33Kwa6Qg 

 

 

물론 라우터 관련 영상도 찾았다. 사실 당장 내가 딱 원하는 내용은 아니었지만, 나중에 충분히 필요할 것 같은 내용이다 

https://www.youtube.com/watch?v=uF2lqBluQV8 

 

 

https://github.com/vercel/next.js/issues/7479

 

How to mock useRouter? · Issue #7479 · vercel/next.js

Question about Next.js I'm want to make sure my component renders correctly with useRouter hook (actually I'm trying to understand how new dynamic routing works), so I have code: import Rea...

github.com

오우....아무래도 내 생각엔 라우팅 테스팅 관련해서 이 이슈를 들여다보는게 최고인 것 같다. 

라우트 테스팅 관련해서 양질의 자료가 정말 많다.

 

https://github.com/vercel/next.js/blob/875b205b57a4bb3e3016279268e334fee5692c29/packages/next/client/index.js#L211

 

GitHub - vercel/next.js: The React Framework

The React Framework. Contribute to vercel/next.js development by creating an account on GitHub.

github.com

 

 

 

const route = (pathname: string) => {
  useRouter.mockImplementation(() => ({
    pathname,
  }));
};

 

 

 

 

 

    <RouterContext.Provider
      value={{
        route,
        pathname,
        query,
        asPath,
        push,
        replace,
        reload,
        back,
        prefetch,
        beforePopState,
        isFallback,
        events,
      }}
    >
      {tree}
    </RouterContext.Provider>

 

 

2.타입스크립트 Pick 

 

https://kyounghwan01.github.io/blog/TS/fundamentals/utility-types/#pick

 

typescript - 유틸리티 타입 (Partial, Omit, Pick)

typescript - 유틸리티 타입 (Partial, Omit, Pick), 타입스크립트, ts

kyounghwan01.github.io

지난번에 Partial을 찾아봤었는데, 오늘은 Pick을 찾아볼 차례. 

 

next에서 router를 모킹하려는데, 뭔가 잘안된다..ㅜ 

https://w11i.me/nextjs-userouter-testing

 

Next.js, useRouter hook, and testing | w11i.me

A quick tip on how to test Next.js components which utilize the useRouter hook.

w11i.me

이 자료를 참고하려 했으나, 1년전이랑 지금이랑 다르다. 그래서 타입 같은 부분들이나, import해오는 경로나 다르게 적어줘야한다. 그래서 next 레포지토리 내부를 확인하면서 경로들을 가져오는 중이다. 

그리고 타입 같은 부분들도 저 글과 현재와는 달라서, 타입도 다시 지정해줘야 한다. 

 

import React from 'react';
import { NextRouter } from 'next/router';
import { RouterContext } from 'next/dist/shared/lib/router-context';

export function withTestRouter(
  tree: React.ReactElement,
  router: Partial<NextRouter>,
) {
  const {
    route = '',
    pathname = '',
    query = {},
    asPath = '',
    basePath = '',
    isLocaleDomain = true,
    push = async () => true,
    replace = async () => true,
    reload = () => null,
    back = () => null,
    prefetch = async () => undefined,
    beforePopState = () => null,
    isFallback = false,
    events = {
      on: () => null,
      off: () => null,
      emit: () => null,
    },
    isReady = false,
    isPreview = false,
  } = router;

  return (
    <RouterContext.Provider
      value={{
        route,
        pathname,
        query,
        asPath,
        push,
        replace,
        reload,
        back,
        prefetch,
        beforePopState,
        isFallback,
        events,
        basePath,
        isLocaleDomain,
        isReady,
        isPreview,
      }}
    >
      {tree}
    </RouterContext.Provider>
  );
}

요렇게 현재 next버전에 맞게 라우터를 모킹하도록 만들었다. 

 

 

describe('NavBar', () => {
  const renderNavBar = (pathname: string) =>
    render(
      withTestRouter(<NavBar />, {
        pathname,
      }),
    );

  describe('recoen. 을 클릭하면', () => {
    it('메인 페이지로 이동한다', () => {
      const { getByText } = renderNavBar('/');
      const recoen = getByText(/recoen./);
      expect(recoen).toHaveAttribute('href', '/');
    });
  });

  describe('detail 페이지에 있으면', () => {
    it('position이 absolute로 바뀐다', () => {
      const { getByTestId } = renderNavBar('/article/[id]');
      const fixedContainer = getByTestId('fixedContainer');

      expect(fixedContainer).toHaveStyleRule('position', 'absolute');
    });
  });
});

이렇게 작성했는데 안된다. pathname이 /article/[id]이면 absolute가 나와야하는데,

fixed를 반환받는다.. 

아. 근데 진전이 있다. 

 

  const resolvePosition = () => {
    const pathname = router.pathname;
    console.log(pathname);

이렇게 pathname을 확인해보니, jest 환경에서 내가 원하는 pathname이 들어가고 있었다. 

 

pathname에 /article/[id]가 잘 나온다

오... 이것은 확실한 진전이다. 그러면 문제의 범위가 좁혀졌다. 이제 내가 확인해야 할 문제는 스타일이 변경되지 않는 문제이다. 

 

아... 찾았다. 결국 오타의 문제 였다...ㅜ

aricle 이라고 적혀있다. article이 아니라!
기분 좋은 초록색

아주 기분 좋게 테스트가 잘 통과한다👍😆 

나름 의미 있는 탐색의 시간이었다. 라우팅 방법을 찾아보고, RouterContext를 가져오기 위해서 next 레포를 뜯어보고, 타입이 안맞는 부분들을 제대로 넣어주기 위해서 또 레포 뜯어보고 그렇게해서 만들어진 withTestRouter.! 이걸로 이제 라우팅 관련할 때마다 테스트 해야겠다. 

 

100%

 

마찬가지로 NavBar도 테스트 커버리지 100% 달성했다. 

 

 

 

3.nextjs 번들분석기가 제대로 동작하지 않는다 : 

 

우선 처음 해본 시도는 에러 일때도 동작하게 만들어놓기. artifact가 없다고 에러가 나오는데, 초반에는 그럴 수 있다고 하니. 일단 에러에도 동작하게 만들어놓고 다음 ci때 한번 확인을 해봐야할 것 같다.

continue-on-error: true

이렇게 했더니 잘 동작한다. 

 

 

 

 

'TIL(Today i learned)' 카테고리의 다른 글

[TIL-2022.10.27] Evaluate란 무엇일까  (0) 2022.10.28
[TIL-2022.10.22] 테스트 코드의 맛  (0) 2022.10.23
[TIL-2022.10.13]  (0) 2022.10.14
[WIL-2022.10.09] 주간회고  (0) 2022.10.10
[TIL - 2022.10.08]  (0) 2022.10.09