레거시 코드에서 TDD(Test-Driven Development)를 적용하는 것은 쉽지 않습니다. 특히 .NET Framework 기반 레거시 코드는 일반적으로 테스트 가능성이 낮고, 의존성이 강하게 얽혀 있는 경우가 많습니다.
이번 글에서는 .NET Framework + MSTest를 기반으로 레거시 코드에서 TDD를 적용하는 방법을 다룹니다.
- ✅ 기존 레거시 코드를 테스트 가능하게 수정
- ✅ Moq을 사용해 외부 의존성을 Mocking
- ✅ MSTest로 첫 테스트 작성 및 성공시키기
🚀 1. TDD란 무엇인가?
TDD(Test-Driven Development)는 "테스트 주도 개발"을 의미합니다. 말 그대로 코드를 작성하기 전에 테스트 코드부터 작성하고, 테스트가 통과할 수 있도록 코드를 작성한 뒤 리팩토링하는 과정을 반복합니다.
TDD는 다음과 같은 3단계 사이클로 이루어집니다:
- RED – 실패하는 테스트 작성
- GREEN – 테스트가 통과하도록 코드 작성
- REFACTOR – 코드 리팩토링 및 성능 개선
"테스트가 코드보다 먼저 작성된다."
🚩 2. 레거시 코드에서의 문제점
레거시 코드에서 TDD 적용이 어려운 이유는 다음과 같습니다:
- ✅ 테스트 코드가 작성되지 않은 상태
- ✅ static 메서드 사용 → Mocking 불가능
- ✅ 데이터베이스, 네트워크 등 외부 시스템에 의존
- ✅ 비즈니스 로직이 직접 코드에 연결됨
🔥 레거시 코드 예제
public static class OrderService
{
public static bool ProcessOrder(int orderId)
{
var order = Database.GetOrderById(orderId);
if (order == null) return false;
PaymentGateway.Charge(order.TotalAmount);
Logger.Log($"Order {orderId} processed.");
return true;
}
}
🛠️ 3. MSTest 기반 테스트 환경 설정 (.NET Framework)
🚀 1) MSTest 설치
Visual Studio에서 다음과 같이 설정합니다:
- 새 프로젝트 생성 → .NET Framework → Unit Test Project(MSTest) 선택
- NuGet 패키지 설치
Install-Package MSTest.TestFramework
Install-Package MSTest.TestAdapter
Install-Package Moq
🚀 2) 첫 테스트 작성
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class OrderServiceTests
{
[TestMethod]
public void TestSample()
{
// Arrange
int value1 = 1;
int value2 = 1;
// Act
int result = value1 + value2;
// Assert
Assert.AreEqual(2, result);
}
}
🚀 3) 테스트 실행
- 테스트 탐색기 열기 → Ctrl + E, T
- 테스트 실행 후 결과 확인 가능
🌟 4. 기존 레거시 코드 수정하기 (인터페이스 적용)
🔥 기존 코드 (테스트 불가 코드)
public static class Database
{
public static Order GetOrderById(int orderId)
{
// 실제 데이터베이스 접근 로직
}
}
🔥 수정 코드 (인터페이스 적용)
public interface IDatabase
{
Order GetOrderById(int orderId);
}
public class Database : IDatabase
{
public Order GetOrderById(int orderId)
{
// 실제 데이터베이스 접근 로직
return new Order { OrderId = orderId, TotalAmount = 100 };
}
}
🚀 OrderService 수정 코드
public class OrderService
{
private readonly IDatabase _database;
public OrderService(IDatabase database)
{
_database = database;
}
public bool ProcessOrder(int orderId)
{
var order = _database.GetOrderById(orderId);
if (order == null) return false;
return true;
}
}
🚀 5. Mocking 적용 및 테스트 작성
[TestMethod]
public void TestWithMock()
{
// Arrange
var mockDatabase = new Mock<IDatabase>();
mockDatabase.Setup(db => db.GetOrderById(It.IsAny<int>()))
.Returns(new Order { OrderId = 1, TotalAmount = 100 });
var service = new OrderService(mockDatabase.Object);
// Act
var result = service.ProcessOrder(1);
// Assert
Assert.IsTrue(result);
}
🎯 결과
- ✅ .NET Framework + MSTest 환경 설정 완료
- ✅ 인터페이스 추출 및 의존성 주입 완료
- ✅ Moq으로 Mocking 적용 완료
- ✅ 첫 번째 테스트 성공
🚀 다음 편 예고
👉 다음 글에서는 외부 API 호출 및 Mocking 적용하는 예제를 다루겠습니다.
👉 통합 테스트와 단위 테스트의 차이점, 테스트 데이터베이스 설정 방법까지 상세히 설명하겠습니다.