본문 바로가기
안드로이드(kotlin)

안드로이드에서 API 데이터를 mock 데이터로 받기 - node.js

by 기계공학 주인장 2025. 3. 4.
반응형

안드로이드에서 mock 데이터를 사용하여 디버깅이나 테스트를 할 수 있는 방법이 있습니다.

 

mock 데이터를 사용하여 테스트하는 방법은 여러 방법이 있지만

 

이번 포스팅에서는 node.js를 사용하여 로컬 서버를 만들어서 테스트 하는 방법을 알아보겠습니다.

 

node.js를 할 때의 장점은 build variant를 변경하는 것만으로 바로 테스트를 실시할 수 있다는 점입니다.


node.js를 사용하여 mock 데이터로 안드로이드 테스트하기

 

node.js 설치하기

다음 커맨드를 사용하여 node.js를 설치합니다.

 

brew install node

 

Windows를 사용하는 분들은 다음 페이지에서 직접 설치할 수 있습니다.

 

https://nodejs.org/ko

 

Node.js — 어디서든 JavaScript를 실행하세요

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 

설치 완료 후 터미널에서 다음과 같은 커맨드를 실시합니다.

 

node --version

 

현재 설치된 node.js의 버전이 제대로 출력된다면 설치가 정상적으로 된 것입니다.


안드로이드 프로젝트 셋업하기

먼저 API의 URL을 Build Variant로 나뉠 수 있게 다음과 같은 형태로 셋업 할 필요가 있습니다.

 

(혹시 기존 프로젝트에서 API를 사용할 때 URL이 코드 or 다른 로컬 파일에서 사용하고 있을 경우 다음과 같이 수정이 필요합니다.)

 

// 스토어 게시용 build variant
store {
    buildConfigField STRING, API_URL, '"https://www.realurl.com/"'
}


// 디버그용 build variant
debug {
    buildConfigField STRING, API_URL, '"https://www.debug_url.com/"'
}

// 디버그-mock용 build variant
debug_mock {
    buildConfigField STRING, API_URL, '"http://10.0.2.2:8080/"'
}

 

위와 같이 정의했으면 아마 Retrofit과 API_URL을 사용해서 API로 부터 데이터를 가져올 수 있을 거라 생각합니다.

 

중요한 것은 debug_mock 같은 build variant를 새롭게 만들어서 거기서 사용하는 URL을

 

http://10.0.2.2:8080/로 설정하는 것입니다.

 

해당 주소는 안드로이드의 에뮬레이터가 사용하는 주소이기 때문에 해당 주소를 통해 mock 테스트용 node.js 서버와 연결할 수 있습니다.


node.js mock 서버용 프로젝트 셋업

이제 mock로 사용할 데이터와 run script를 작성해야 합니다.

 

VS code 등을 사용해서 하나의 폴더를 만들고 그 안에 mock.js 같은 js 파일을 하나 생성합니다.

 

(해당 폴더가 mock용 데이터를 담는 프로젝트가 됩니다.)

 

생성된 mock.js에 다음과 같은 코드를 적습니다.

mock.js
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');

// 서버 포트 설정
const PORT = 8080;

// 서버 생성
const server = http.createServer((req, res) => {
  // URL 파싱
  const parsedUrl = url.parse(req.url, true);
  const pathname = parsedUrl.pathname;
  
  console.log(`Request received: ${pathname}`);
  
  // API 요청 패턴 확인 (/api/{api_name1}/{api_name2})
  if (pathname.startsWith('/api/')) {
    handleApiRequest(pathname, res);
  } else {
    // API 요청이 아닌 경우 404 반환
    res.writeHead(404, {'Content-Type': 'application/json'});
    res.end(JSON.stringify({ error: 'Not Found' }));
  }
});

// API 요청 처리 함수
function handleApiRequest(pathname, res) {
  // URL 경로 분리
  const pathParts = pathname.split('/').filter(part => part !== '');
  
  // 경로가 /api/{api_name1}/{api_name2} 형식인지 확인
  if (pathParts.length >= 3 && pathParts[0] === 'api') {
    const apiName1 = pathParts[1];    // 디렉토리 이름
    const apiName2 = pathParts[2];    // JSON 파일 이름
    
    // Mock 데이터 파일 경로 구성
    const mockFilePath = path.join(__dirname, apiName1, `${apiName2}.json`);
    
    console.log(`Looking for mock data at: ${mockFilePath}`);
    
    // 파일 존재 여부 확인 후 응답
    fs.access(mockFilePath, fs.constants.F_OK, (err) => {
      if (err) {
        // 파일이 없는 경우
        console.error(`Mock file not found: ${mockFilePath}`);
        res.writeHead(404, {'Content-Type': 'application/json'});
        res.end(JSON.stringify({ error: 'Mock data not found' }));
        return;
      }
      
      // 파일이 있는 경우 읽어서 응답
      fs.readFile(mockFilePath, 'utf8', (err, data) => {
        if (err) {
          console.error(`Error reading mock file: ${err}`);
          res.writeHead(500, {'Content-Type': 'application/json'});
          res.end(JSON.stringify({ error: 'Internal server error' }));
          return;
        }
        
        try {
          // JSON 파싱 시도 (유효한 JSON인지 확인)
          const jsonData = JSON.parse(data);
          
          // 응답 헤더 설정 및 데이터 전송
          res.writeHead(200, {'Content-Type': 'application/json'});
          res.end(data);
          console.log(`Successfully served mock data for: ${pathname}`);
        } catch (e) {
          // JSON 파싱 실패 시
          console.error(`Invalid JSON in mock file: ${mockFilePath}`);
          res.writeHead(500, {'Content-Type': 'application/json'});
          res.end(JSON.stringify({ error: 'Invalid JSON in mock file' }));
        }
      });
    });
  } else {
    // API 경로 형식이 맞지 않는 경우
    res.writeHead(400, {'Content-Type': 'application/json'});
    res.end(JSON.stringify({ error: 'Invalid API path format' }));
  }
}

// 서버 시작
server.listen(PORT, () => {
  console.log(`Mock API server running at http://localhost:${PORT}`);
  console.log(`Example API endpoint: http://localhost:${PORT}/api/{api_name1}/{api_name2}`);
});

 

코드 중에서 if (filePath.startsWith("{사용하려는 API}")) 부분을 반드시 자신의 API의 엔드 포인트로 적어야 합니다.

 

예를 들면 다음과 같습니다.

 

기존 API: www.debug_test/api/documents/~~.com

 

⇨ if (filePath.startsWith("/api/"))

 

즉, API의 URL이 /api/로 시작한다면 무조건 해당 node.js 서버를 통과해서 결과를 얻게 한다는 의미입니다.

 

 

이후 해당 js 파일이 있는 위치에서 터미널을 실행하여 다음 커맨드를 실행합니다.

 

node mock.js

 

그럼 방금 정의한 코드를 node.js를 사용하여 실행하게 된다.

 

문제없이 실행된다면 이제부터 mock 데이터를 만들어본다.


node.js 프로젝트 안에 mock 데이터 만들기

위에서 정의한 코드를 보면

 

각각의 mock 데이터에 대해 다음과 같은 구성으로 파일을 만들 필요가 있다는 것을 알 수 있다.

 

예를 들어 www.debug_test/api/documents 같은 API에 대해 mock 데이터를 만들고 싶다면

 

다음과 같은 구성으로 만들어야 한다.

 

/your_server_directory
  /server.js
  /ap1
    /document.json
    /details.json
  /api2
    /categories.json
    /items.json

 

위와 같이 만들고자 하는 API의 URL을 바탕으로 폴더 & JSON 파일을 만들어야 한다.

 

각각의 파일에 들어가야 할 내용은 다음과 같다.

 

  • JSON 파일: 해당 API를 호출했을 때 반환해야 할 Response
// 상태 코드를 포함한 JSON 파일 구조 예시
{
  "_meta": {
    "statusCode": 200
  },
  "error": "Aauthorized",
  "message": "Authentication done"
}

 

 

위와 같이 설정이 끝나면 이제 js 파일이 있는 위치에서 터미널을 실행하여 다음 커맨드를 실행하여 mock 테스트를 할 수 있습니다.

 

node mock.js

 


node.js를 사용하여 mock 데이터로 안드로이드 테스트하기 - 정리

간단하게 정리하면 다음과 같습니다.

 

  1. node.js 설치
  2. 안드로이드 build variants 설정
  3. node.js 프로젝트 셋업
  4. node.js 파일을 실행하여 mock 환경에서 테스트

 

반응형


"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."


댓글