유닛 테스트 기초 (Unit Testing Basics)
자바스크립트에서 코드를 작성할 때, 제대로 작동하는지 확인하는 방법 중 하나로 유닛 테스트가 있다. 유닛 테스트는 코드의 작은 단위를 독립적으로 검증하며, 전체 애플리케이션의 안정성을 높여준다. 이번에는 유닛 테스트의 기본 개념부터 심화된 활용까지 코드와 함께 자세히 알아보려고 한다.
유닛 테스트를 잘 다루면 코드의 신뢰성을 높이고, 수정할 때도 안심할 수 있다. 하나씩 단계별로 풀어보자.
유닛 테스트란 무엇인가
유닛 테스트는 함수나 모듈 같은 코드의 개별 단위를 테스트하는 방법이다. 전체 시스템을 한 번에 확인하는 대신, 작은 조각들을 따로 검증한다:
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // 5
위 함수를 테스트하려면 입력값을 넣고 출력값이 예상과 같은지 확인하면 된다. 이 과정을 자동화하는 도구를 사용하면 편리하다.
1. 간단한 유닛 테스트 작성
자바스크립트에서 유닛 테스트를 위해 assert
모듈을 활용해보자:
const assert = require("assert");
function add(a, b) {
return a + b;
}
assert.strictEqual(add(2, 3), 5, "2 + 3은 5여야 한다");
assert.strictEqual(add(0, 0), 0, "0 + 0은 0이어야 한다");
console.log("모든 테스트 통과!");
assert.strictEqual
로 결과값과 기대값을 비교했다. 오류가 없으면 메시지가 출력된다.
2. 테스트 프레임워크 사용: Mocha
수동으로 assert
를 쓰는 대신, Mocha
같은 테스트 프레임워크를 사용하면 더 체계적으로 관리할 수 있다:
// 설치: npm install mocha
const assert = require("assert");
describe("add 함수 테스트", () => {
it("2와 3을 더하면 5가 된다", () => {
function add(a, b) {
return a + b;
}
assert.strictEqual(add(2, 3), 5);
});
it("0과 0을 더하면 0이 된다", () => {
function add(a, b) {
return a + b;
}
assert.strictEqual(add(0, 0), 0);
});
});
describe
로 테스트 그룹을 만들고, it
으로 개별 테스트를 정의했다. npm test
로 실행하면 결과를 볼 수 있다.
3. 비동기 함수 테스트
비동기 코드를 테스트하려면 약간의 추가 작업이 필요하다:
const assert = require("assert");
function fetchData() {
return new Promise((resolve) => {
setTimeout(() => resolve("데이터"), 1000);
});
}
describe("비동기 함수 테스트", () => {
it("1초 후 데이터를 반환한다", async () => {
const result = await fetchData();
assert.strictEqual(result, "데이터");
});
});
async
와 await
를 사용해서 비동기 결과를 기다린 후 검증했다.
4. 모킹(Mocking)으로 의존성 관리
외부 의존성이 있는 코드를 테스트할 때, sinon
같은 라이브러리로 모킹을 해보자:
// 설치: npm install sinon mocha --save-dev
const assert = require("assert");
const sinon = require("sinon");
function getUserData(fetch) {
return fetch("https://api.example.com/user");
}
describe("getUserData 테스트", () => {
it("API 호출 결과를 반환한다", async () => {
const fakeFetch = sinon.stub().resolves("유저 데이터");
const result = await getUserData(fakeFetch);
assert.strictEqual(result, "유저 데이터");
});
});
sinon.stub
으로 가짜 함수를 만들어 실제 API 호출 없이 테스트했다.
5. 에러 상황 테스트
함수가 에러를 잘 처리하는지 확인해보자:
const assert = require("assert");
function divide(a, b) {
if (b === 0) throw new Error("0으로 나눌 수 없다");
return a / b;
}
describe("divide 함수 테스트", () => {
it("0으로 나누면 에러가 발생한다", () => {
assert.throws(() => divide(5, 0), {
message: "0으로 나눌 수 없다"
});
});
it("정상적인 나눗셈은 결과를 반환한다", () => {
assert.strictEqual(divide(6, 2), 3);
});
});
assert.throws
로 에러를 검증하고, 정상 동작도 확인했다.
6. 복잡한 객체 테스트
객체를 다룰 때는 깊은 비교가 필요하다:
const assert = require("assert");
function createUser(name, age) {
return { name, age };
}
describe("createUser 테스트", () => {
it("이름과 나이를 포함한 객체를 반환한다", () => {
const expected = { name: "홍길동", age: 30 };
const result = createUser("홍길동", 30);
assert.deepStrictEqual(result, expected);
});
});
deepStrictEqual
로 객체의 속성을 모두 비교했다.
7. 테스트 더블(Test Double) 활용
테스트 더블로 복잡한 의존성을 대체해보자:
const assert = require("assert");
class Database {
getData() {
return "실제 데이터";
}
}
class Service {
constructor(db) {
this.db = db;
}
fetch() {
return this.db.getData();
}
}
describe("Service 테스트", () => {
it("가짜 DB로 데이터 가져오기", () => {
const fakeDb = { getData: () => "가짜 데이터" };
const service = new Service(fakeDb);
assert.strictEqual(service.fetch(), "가짜 데이터");
});
});
가짜 객체를 만들어 실제 데이터베이스 없이 테스트를 진행했다.
8. 반복 테스트 자동화
여러 입력값을 한 번에 테스트하려면 반복문을 활용한다:
const assert = require("assert");
function multiply(a, b) {
return a * b;
}
describe("multiply 함수 테스트", () => {
const cases = [
[2, 3, 6],
[0, 5, 0],
[1, 1, 1]
];
cases.forEach(([a, b, expected]) => {
it(`${a}와 ${b}를 곱하면 ${expected}가 된다`, () => {
assert.strictEqual(multiply(a, b), expected);
});
});
});
배열을 순회하며 여러 경우를 자동으로 테스트했다.
9. 성능과 유지보수성에 미치는 영향
유닛 테스트가 코드에 어떤 영향을 주는지 살펴보자:
- 성능: 테스트 실행에 시간이 걸릴 수 있지만, 버그를 줄여 전체 개발 속도를 높인다.
- 유지보수성: 코드 변경 후에도 테스트로 바로 확인할 수 있어 안정성이 유지된다.
작은 단위를 테스트하며 전체 시스템의 신뢰성을 확보하는 점이 핵심이다.
마무리
유닛 테스트는 코드의 작은 부분을 검증하며 전체 품질을 높여준다. 기본적인 함수 테스트부터 비동기, 모킹, 에러 처리까지 다양한 상황에서 활용할 수 있다. 꾸준히 작성하면 코드에 대한 자신감이 생길 것이다.
'코딩 공부 > 자바스크립트' 카테고리의 다른 글
79. 자바스크립트 DevTools 심화 (Advanced DevTools Usage) (1) | 2025.03.26 |
---|---|
78. 자바스크립트 Jest 사용법 (Using Jest) (0) | 2025.03.26 |
76. Angular 기초 (Angular Basics) (0) | 2025.03.25 |
75. Vue.js 기초 (Vue.js Basics) (0) | 2025.03.25 |
74. Node.js 기초 (Node.js Basics) (2) | 2025.03.25 |