개발 지식

개발 지식

PHP PHPUnit으로 테스트 가능한 코드 구조 만들기

페이지 정보

profile_image
영삼이
0건 172회 25-03-28 23:09

본문

✅ PHPUnit으로 테스트 가능한 코드 구조 만들기

PHPUnit을 사용한 단위 테스트는 코드 품질을 높이고 버그를 줄이는 데 매우 효과적입니다. 하지만 테스트 가능하게 설계된 구조가 뒷받침되지 않으면 의미 없는 테스트만 늘어나게 됩니다. 이 글에서는 테스트 가능한 코드 구조를 어떻게 만들 것인가에 초점을 맞춥니다.


🎯 테스트 가능한 구조의 핵심 원칙

  1. 순수 함수화 (Pure Function)

  2. 의존성 주입 (Dependency Injection)

  3. 사이드 이펙트 최소화

  4. 비즈니스 로직과 IO 분리


🧱 나쁜 예시: 테스트하기 어려운 코드

[code=php]
class UserService {
    public function register(string $email, string $name) {
        $pdo = new PDO(...);
        $stmt = $pdo->prepare('INSERT INTO users VALUES (?, ?)');
        $stmt->execute([$email, $name]);
    }
}
[/code]
  • DB 연결이 직접 포함되어 있어 테스트 불가능

  • 의존성 주입 없이 강한 결합


✅ 개선된 구조: 의존성 주입 활용

[code=php]
interface UserRepository {
    public function save(string $email, string $name): void;
}
[/code]

```php
[code=php]
class UserService {
    public function __construct(private UserRepository $repo) {}

    public function register(string $email, string $name): void {
        $this->repo->save($email, $name);
    }
}
[/code]

이제 UserRepository는 테스트용 가짜(Fake)로 대체 가능


🧪 PHPUnit 테스트 예시

[code=php]
use PHPUnit\Framework\TestCase;

class UserServiceTest extends TestCase {
    public function testRegisterCallsRepository() {
        $repo = $this->createMock(UserRepository::class);
        $repo->expects($this->once())
             ->method('save')
             ->with('kim@example.com', 'Kim');

        $service = new UserService($repo);
        $service->register('kim@example.com', 'Kim');
    }
}
[/code]
  • 저장소 호출 여부 검증 가능

  • 사이드 이펙트 없음

  • 빠르고 안정적인 테스트


⚙️ 기타 팁

  • 컨트롤러 테스트보다 서비스/도메인 로직 테스트 우선

  • 외부 서비스(API, Mail 등)는 Mock 또는 Stub 활용

  • PHPUnit dataProvider로 다양한 케이스 테스트


✅ 요약

항목 나쁜 구조 좋은 구조
의존성 주입 ❌ 없음 ✅ 있음
테스트 격리 ❌ 불가능 ✅ 가능
로직 분리 ❌ 없음 ✅ 명확
테스트 속도 ❌ 느림 ✅ 빠름

테스트는 PHPUnit보다도 테스트 가능한 구조 설계가 먼저입니다.
그 구조를 갖춰야 테스트가 진짜 효과를 발휘합니다.


댓글목록

등록된 댓글이 없습니다.