본문 바로가기
Aplication test

리액트 테스트코드 - 1

by ddddbbbb 2023. 10. 28.

테스트 코드를 짜는데 있었던 어려움 :

Error List:
1)  jest 설정에서 이미지형식을 제외시켜도 에러가 뜸
2) 컴포넌트에서 사용한 useNavigate()에서 <Router>에서 벗어난 영역에서 사용한다는 에러가뜸  
 

1) 1번 해결 (  jest 설정에서 이미지형식을 제외시켜도 에러가 뜸 )

빠르게 테스트 코드를 짤수있을 줄 알았는데 생각도 못한 곳에서 에러 사항이 있었다
UI 테스트를 위해 간이 테스트 코드를 아래와 같이 짰다 
 

Page 컴포넌트에 zzz라는 문자가 랜더링 되는지 테스트 하는 코드이다 

import Page from '../components/main/Page';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

describe('render', () => {
  it('main_render', () => {
    const { container } = render(<Page />);

    //main에 zzz가 있는지 확인 
     expect(container).toHaveTextContent('zzz'); 
  });
});

 
 
 
당연히 zzz 라는 문구를 일부러 넣어놨으니 될 줄알았는데 

import Img_Man from "../../assets/main/man_main.png";

 
 
 
이부분에서 아래와 같은 에러가 발생했다 

 FAIL  src/test/main.test.tsx
  ● Test suite failed to run
                                                                                                    
    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    C:\Users\jo\Desktop\임시(2)\projects\voice_todolist\src\assets\main\man_main.png:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){�PNG


    SyntaxError: Invalid or unexpected token

      1 | import React,{useEffect, useState} from "react";
      2 | import FallBoxs from "./FallBoxs";
    > 3 | import man_main from "../../assets/main/man_main.png";
        | ^

 
 
 
jest 설정파일에서 transformIgnorePatterns에 이미지 파일 형식을 추가해주면 될줄알았는데
다시 읽어 보니 노드모듈 적용시 해당방식으로 진행하는 거였다 ,,,, 
 
 
 
 
js가 아닌 모듈은 moduleNameMapper을 통해 스텁(요청에 대한 응답을 정의해두는 것)할 수 있다고 한다.
그래서 아래와 jest.config.js 파일을 변경했다
 

module.exports = {
  // 특정 파일 또는 디렉토리를 테스트 파일로 간주하지 않도록 패턴을 지정합니다.
  //
  transformIgnorePatterns: [
    "/node_modules/",
  ],
  // 파일 변환 방법을 설정합니다.
  // 여기서는 JavaScript 및 TypeScript 파일에 대해 'ts-jest' 변환기를 사용합니다.
  transform: {
    "^.+\\.(ts|tsx|js|jsx)$": "ts-jest",
  },

  // 모듈 이름을 매핑하여 import 문에 대한 사용자 지정 경로를 정의합니다.
  // 이 설정에서는 'src/'로 시작하는 import 경로를 실제 'src' 디렉토리로 연결합니다.
  moduleNameMapper: {
    "^src/(.*)$": "<rootDir>/src/$1",
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/assetsTransformer.js',
    '\\.(css|less)$': '<rootDir>/assetsTransformer.js'
  },

  // 테스트 환경을 지정합니다. 여기서 'jsdom' 환경을 사용합니다.
  testEnvironment: "jsdom",
};

 
경로를 매핑 시켰으니까 해당하는 파일 (assetsTransformer.js)이 존재만 해도 테스트통과가 되지만 테스트 동작은 이뤄지지않는다 
 
 
 
 
그래서 파일이름을 모듈이름으로 설정해서 테스트때 같은지 비교하는 테스트를 추가하는 코드를 넣어줬습니다

const path = require("path");

// 파일이름을 모듈이름으로 설정해서 테스트시 같은지 확인하며 통과시킴
module.exports = {
  process(src, filename, config, options) {
    return `module.exports = ${JSON.stringify(path.basename(filename))};`;
  },
};

 
 
 
 

1) 2번 해결 ( 컴포넌트에서 사용한 useNavigate()에서 에서 벗어난 영역에서 사용한다는 에러가뜸 )

 
아래와 같은 에러가 발생했다 

  ● render › main_render                                                                            
                                                                                                    
    useNavigate() may be used only in the context of a <Router> component.                          
                                                                                                    
      16 |   const angles = [0, 2, -8, -5, 2, -5];                                                  
      17 |                                                                                          
    > 18 |   const navigate=useNavigate();

 
폴더구조는 위와 같았고 Page라는 컴포넌트에 필요한 컴포넌트를 다 import 하고 pages에 Main에는 Page하나만 import 하는 형식이였는데
 
해당 코드들이 FallBoxs의 코드들이여서 라우터 구조도 바꿔 보고 시도를 하다가 

import Page from '../components/main/Page';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

describe('render', () => {
  it('main_render', () => {
    const { container } = render(<Page />);

    //main에 zzz가 있는지 확인 
     expect(container).toHaveTextContent('zzz'); 
  });
});

 
테스트 코드를 보니 저 Page가 랜더함수에 의해 동작되서 생기는 문제가 아닐까는 생각이 들었고 ,,, 맞았다 ,,,, 
 
 
 
아래와 같이 라우터를 추가해주고 해결했다 ,,,, 
 

import React from 'react';
import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom'; // MemoryRouter를 가져옴
import '@testing-library/jest-dom/extend-expect';
import Page from '../components/main/Page';

describe('render', () => {
  it('main_render', () => {
    const { container } = render(
      <MemoryRouter> {/* MemoryRouter로 감싸기 */}
        <Page />
      </MemoryRouter>
    );

    // main에 zzz가 있는지 확인
    expect(container).toHaveTextContent('zzz');
  });
});

 
 
드디어 ,,,, 그린이 ..!! ㅜㅜㅜ

 
 
 
 
참고 : https://flamingotiger.github.io/frontend/Testing/jest-image-error/

'Aplication test' 카테고리의 다른 글

테스트 코드의 의의  (0) 2024.01.26
리액트 테스트코드 - add  (0) 2023.10.31
리액트 테스트코드 - list , header  (0) 2023.10.30
리액트 테스트 코드 - 2  (0) 2023.10.30
리액트 테스트코드 - intro  (0) 2023.10.25