Test Code

이경헌·2024년 8월 28일

테스트 주도 개발(Test-Driven Development, TDD)

테스트 주도 개발(Test-Driven Development, TDD)은 소프트웨어 개발 방법론 중 하나로, 소프트웨어 개발 과정에서 코드를 작성하기 전에 테스트를 먼저 작성하는 방식을 말합니다. 이 방법론은 "테스트가 모든 개발의 중심"이라는 철학을 바탕으로 합니다.

TDD의 핵심 개념

  1. 작은 단위의 반복적인 개발 사이클: TDD는 매우 짧고 반복적인 개발 사이클을 따릅니다. 이 사이클은 "Red-Green-Refactor"로 요약됩니다.
  • Red (실패하는 테스트 작성): 아직 구현되지 않은 기능이나 변경 사항에 대해 테스트 코드를 작성하고, 이를 실행하여 실패하는지 확인합니다. 이 단계에서는 테스트가 통과하지 않는 것이 정상입니다.
  • Green (테스트를 통과시키기 위한 최소한의 코드 작성): 작성한 테스트가 통과하도록 코드를 작성합니다. 이때는 가장 단순한 형태로 테스트가 통과할 수 있는 코드만 작성합니다.
  • Refactor (코드 개선): 테스트가 통과한 후, 코드의 품질을 높이기 위해 리팩토링을 수행합니다. 리팩토링 과정에서도 모든 테스트가 통과해야 합니다.
  1. 테스트 우선: TDD에서는 테스트가 개발의 출발점입니다. 먼저 원하는 기능의 테스트를 작성하고, 이후에 해당 기능을 구현합니다. 이렇게 하면 개발자는 자신이 작성한 코드가 요구 사항을 충족하는지 즉시 확인할 수 있습니다.

  2. 작은 단계로 개발: TDD는 기능을 작은 단위로 나누어 개발하는 것을 강조합니다. 이는 테스트를 쉽게 작성하고 유지 보수하기 위함입니다.

@MockBean vs @SpyBean

@MockBean@SpyBean은 둘 다 Spring Boot 테스트에서 빈의 동작을 제어하는 데 사용되는 어노테이션이지만, 사용하는 목적과 방식에 차이가 있습니다.

@MockBean

설명

  • @MockBean은 Spring Boot의 테스트 컨텍스트에서 모의 객체(mock object)를 생성하고 주입하는 데 사용됩니다.
  • @MockBean은 Mockito를 사용하여 빈의 동작을 모의(mock)합니다.
  • 주로 빈의 메서드가 호출되지 않거나, 특정 동작을 가짜로 만들어야 할 때 사용합니다.

사용 목적

  • 의존성 주입: 테스트 대상 클래스의 의존성을 가짜 객체로 대체하여 테스트합니다.
  • 인터페이스 모의: 실제 구현 없이 인터페이스만 모의하여 테스트를 진행할 때 유용합니다.
  • 외부 시스템 대체: 데이터베이스, 웹 서비스 등 외부 시스템의 동작을 모의하여 테스트합니다.

예제

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceTest {

    @MockBean
    private MyDependency myDependency; // MyDependency를 모의 객체로 주입

    @Autowired
    private MyService myService;

    @Test
    public void testServiceMethod() {
        // myDependency의 메서드 호출을 모의하여 원하는 값을 반환하도록 설정
        Mockito.when(myDependency.someMethod()).thenReturn("Mocked Value");

        // myService의 메서드 테스트
        String result = myService.serviceMethod();
        assertEquals("Expected Result", result);
    }
}

@SpyBean

@SpyBean은 Spring Boot 테스트에서 실제 빈을 부분적으로 모니터링하고, 특정 메서드만 모의(mock)하거나 검증하는 데 사용됩니다. Mockito의 스파이(spy) 기능을 활용하여 빈의 동작을 조정할 수 있습니다.

설명

  • @SpyBean은 Spring Boot의 테스트 컨텍스트에서 실제 빈을 스파이(spy) 객체로 주입합니다.
  • 실제 빈의 동작을 유지하면서, 일부 메서드의 동작만 모의하거나 검증할 수 있습니다.
  • 빈의 실제 구현과 상태를 유지하면서 특정 동작을 조정할 수 있어 유용합니다.

사용 목적

  • 부분적인 수정: 빈의 전체 동작을 유지하면서 특정 메서드의 동작만 수정하거나 모의(mock)할 때 유용합니다.
  • 실제 구현 사용: 빈의 대부분의 동작을 실제 구현으로 두고, 일부 메서드만 모의하여 테스트합니다.
  • 상태 검증: 실제 빈의 상태를 검증하면서 특정 메서드의 호출을 모니터링할 때 사용합니다.

예제

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceTest {

    @SpyBean
    private MyService myService; // MyService의 실제 빈을 스파이 객체로 주입

    @Autowired
    private MyDependency myDependency;

    @Test
    public void testServiceMethod() {
        // myService의 실제 동작을 유지하면서 특정 메서드만 스파이
        Mockito.doReturn("Mocked Value").when(myService).someMethod();

        // myService의 메서드 테스트
        String result = myService.serviceMethod();
        assertEquals("Expected Result", result);

        // 호출된 메서드 검증
        Mockito.verify(myService).someMethod();
    }
}

0개의 댓글