티스토리 뷰

Next.js

NextJS 14 API Endpoint Test (feat.node-mocks-http, Jest)

YG - 96년생 , 강아지 있음, 개발자 희망 2023. 12. 6. 07:29

 

 

NextJS 14 api route handler를 만들고 endpoint test를 한 과정을 기록했습니다.

 

 

0. 테스트 패키지 선정

 

먼저 NextJS를 테스트하기 위해 사용되는 패키지를 찾아보았습니다.

 

처음에 supertest가 제일 유명하고, gpt에게도 추천받아서 설치했습니다.

 

 

chai-http vs mock-req-res vs node-mocks-http vs supertest | npm trends

Comparing trends for chai-http 4.4.0 which has 349,053 weekly downloads and unknown number of GitHub stars vs. mock-req-res 1.2.1 which has 20,204 weekly downloads and unknown number of GitHub stars vs. node-mocks-http 1.13.0 which has 709,610 weekly downl

npmtrends.com

 

 

그래서 supertest를 설치하고 테스트를 해보았지만 NextJS에서 동작하지 않았습니다.

/**
 * @jest-environment node
 */

import supertest from 'supertest';
import { GET } from '@app/health-check/route';

describe('서버의 상태를 확인한다.', () => {
  it('health-check api를 호출한다.', async () => {
    const response = await supertest(GET).get('/health-check');

    expect(response.body).toBe('health-check');
    expect(response.status).toBe(200);
  });
});

 

 

그래서 NextJS api endpoint test를 검색 후 나온 방법인 node-mocks-http를 사용하기로 했습니다.

다운로드 순위는 2위입니다.

 

 

1. 패키지 설치하기

npm install --save-dev node-mocks-http

 

 

node-mocks-http

Mock 'http' objects for testing Express routing functions. Latest version: 1.13.0, last published: 4 months ago. Start using node-mocks-http in your project by running `npm i node-mocks-http`. There are 149 other projects in the npm registry using node-moc

www.npmjs.com

 

2. NextJS route handler 만들기 (App Router 버전)

app/health-check/route.ts

 

간단히 문자를 반환하는 api를 만들었습니다.

import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
  return NextResponse.json('health-check', { status: 200, statusText: 'OK' });
}

interface HealthRequest {
  name: string;
}

export async function POST(request: NextRequest) {
  const { name }: HealthRequest = await request.json();

  return NextResponse.json(name, { status: 201, statusText: 'CREATED' });
}

 

 

Routing: Route Handlers | Next.js

Create custom request handlers for a given route using the Web's Request and Response APIs.

nextjs.org

 

3. 테스트 파일 만들기

__tests__/api/healthCheck.test.ts

1. 만든 api 함수를 가져옵니다. 

2. createRequest 메서드로 req와 res를 선언합니다.

3. api 함수 안에 req, res를 넣어 사용합니다.

 

/**
 * @jest-environment node
 */

import { NextRequest, NextResponse } from 'next/server';
import { createMocks, createRequest, createResponse } from 'node-mocks-http';
import { GET, POST } from '@app/health-check/route';

type ApiRequest = NextRequest & ReturnType<typeof createRequest>;
type APiResponse = NextResponse & ReturnType<typeof createResponse>;

describe('서버의 상태를 확인한다.', () => {
  it('health-check api를 호출한다.', async () => {
    const { req } = createMocks<ApiRequest, APiResponse>({
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    });

    const response = await GET(req);

    expect(await response.json()).toBe('health-check');
    expect(response.status).toBe(200);
    expect(response.statusText).toBe('OK');
  });

  it('health-check api POST를 호출한다.', async () => {
    const { req } = createMocks<ApiRequest, APiResponse>({
      method: 'POST',
      json: () => ({
        name: 'Add your name in the body',
      }),
    });

    const response = await POST(req);

    expect(await response.json()).toBe('Add your name in the body');
    expect(response.status).toBe(201);
    expect(response.statusText).toBe('CREATED');
  });
});

 

 

주의할 점

api endpoint test를 하기 위해서는 jest.config.js에서 testEnvironment가 node여야 하는데요 만약 jsdom으로 설정이 되어 있다면 에러를 반환합니다.

 

ReferenceError: Response is not defined

 

 

 

jest.config.js

const nextJest = require('next/jest');

const createJestConfig = nextJest({
  dir: './',
});

const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js', '<rootDir>/__tests__/singleton.ts'],
  moduleNameMapper: {
 ...
  },
  testEnvironment: 'jest-environment-jsdom', // << 이 부분
};

module.exports = createJestConfig(customJestConfig);

 

 

저는 react 관련 테스트를 할 때는 jsdom 환경, api 테스트를 할 땐 node 환경을 적용해주려고 했는데요.

 

jest에서 projects라는 것으로 설정할 수 있다고 해서 시도해 보았지만 저는 성공하지 못했습니다.

 

예시)

module.exports = {
  projects: [
    {
      displayName: 'dom',
      testEnvironment: 'jsdom',
      snapshotSerializers: ['enzyme-to-json/serializer'],
      testMatch: ['**/__tests__/**/*.test.js?(x)']
    },
    {
      displayName: 'node',
      testEnvironment: 'node',
      testMatch: [
        '**/__tests__/**/*.test.node.js?(x)',
      ]
    },
  ],
};

 

 

그래서 대안으로 주석으로 테스트 환경을 설정해 주는 방법을 택했습니다.

 

/**
 * @jest-environment node
 */

 

 

api 테스트 성공

 

 


 

createMock으로 했을 때 타입 에러가 나는데 아래와 같이 설정해줘야 했습니다

 

/**
 * @jest-environment node
 */

import { NextRequest, NextResponse } from 'next/server';
import { createMocks, createRequest, createResponse } from 'node-mocks-http';
import { GET, POST } from '@app/health-check/route';

type ApiRequest = NextRequest & ReturnType<typeof createRequest>;
type APiResponse = NextResponse & ReturnType<typeof createResponse>;

describe('서버의 상태를 확인한다.', () => {
  it('health-check api를 호출한다.', async () => {
    const { req } = createMocks<ApiRequest, APiResponse>({
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    });

 

 

 

참고자료

 

 

 

gist:01c6e597fc0df7f27df7c020635fdfac

GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

From the nextjs community on Reddit

Explore this post and more from the nextjs community

www.reddit.com

 

 

Unit Test Next.js API Routes with TypeScript (longer-version)

Testing API routes sucks, especially when using TypeScript. This article covers how to unit test Next.js API routes with TypeScript using…

medium.com

 

 

Is it possible to test Next.js 13 API Route handlers?

Trying to test a very simple route with Jest: import { NextResponse } from 'next/server' export async function GET() { return NextResponse.json({ success: true }) } But when I call await GET() ...

stackoverflow.com

 

 

Use Jest Projects to run both JSDom and Node tests in the same project

Use Jest Projects to run both JSDom and Node tests in the same project - jest.config.js

gist.github.com

 

 

Configuring Jest · Jest

The Jest philosophy is to work great by default, but sometimes you just need more configuration power.

jestjs.io

 

 

Testing Next.js, can't get _getJSONData() · Issue #255 · eugef/node-mocks-http

Hey, I'm currently creating an application using Next and have built some API endpoints. I'm testing the following file import { NextApiRequest, NextApiResponse } from "next"; import { getConfig } ...

github.com

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함