ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TDD] Mockito annotations.zip
    TDD 2024. 8. 31. 22:03

    [@ExtendWith(MockitoExtension.class)]

     

    Mockito 확장 기능을 사용해 단위 테스트를 수행할 수 있도록 해주는 어노테이션

    이 어노테이션을 통해 Mockito가 @Mock, @Spy, @InjectMocks 등의 어노테이션을 인식하고 해당 객체들을 생성하거나 주입할 수 있게 해줌

     

    단위 테스트는 Spring Context 즉 스프링 컨테이너를 로드하지 않기 때문에 우리가 직접 @Mock 를 통해 목객체를 생성하고 @InjectMocks를 통해 해당 mock 객체를 주입받을 놈을 선언해줘야함

     


    [@InjectMocks]

     
    @Mock, @Spy 등 Mock 객체들을 주입받을 놈을 선언하는 어노테이션
    특정 테스트에서의 주인공? 이라고 생각하면 됨
     
    주로 서비스 계층 test에서 쓰이며 서비스 계층에 DAO(repository)를 주입하기 위해
    @Mock repository와 같이 쓰인다
     
    DI를 @Mock이나 @Spy로 생성된 mock객체로 해주는 어노테이션
     


    [@MockBean]

     
    Spring Context를 테스트할때 사용됨
    Spring의 ApplicationContext에 실제 객체의 Bean이 아닌 MockBean을 등록시킬 수 있다!!
     
    @SpringBootTest을 사용하게 되면 ApplicationContext을 모두 로드하는데
    이때 @MockBean 어노테이션을 붙여두면, 실제 Bean이 아닌 Mock 객체를 ApplicationContext에 주입할 수 있다
     
    따라서 @Autowired로 명시한 스프링 빈에
    @MockBean으로 정의한 목객체빈들이 의존성 주입된다!!
     
    즉, @MockBean의 뜻은 말그대로 @Mock + @Bean
    Mock 객체를 생성하고 이를 Bean으로 스프링 컨텍스트에 등록하라!!
    그 의미다!
     

    @SpringBootTest
    public class PuppyServiceTest {
    
        @Autowired
        private TestService testService;   
    
        @MockBean
        private TestRepository testRepository;
    
    }

     
    그리고 이 테스트가 @SpringBootTest인 이유는
    @Autowired @MockBean 모두 스프링 컨텍스트를 필요로 하는 어노테이션이기 때문에
    전체 스프링 컨텍스트를 로드해야하기 때문이다!!
     
    @MockBean을 이용해 가짜 빈을 등록해두지 않으면, 실제 스프링 빈에 등록된 객체가 호출되기 때문에
    모킹을 이용해 가짜 객체를 주입해준 후,
    테스트 메서드 내부에서 해당 객체들의 행동을 미리 가정을 해두는 방식으로 테스트를 진행할 수 있다

    // 메서드 호출과 반환값을 가정
    when(targetClass.doSomething()).thenReturn("반환할 값");
    
    // 메서드 호출시 예외를 가정
    when(targetClass.doSomething()).thenThrow(new SomeException());

    위와같이 행동을 가정할 수 있다
     
    위 when 메서드는 모두 Mockito를 static import한 메서드이고
    호출할 메서드와 반환할 값을 임의로 지정해둘 수 있다
     


    [@Mock]

     
    mock 객체는 가짜 객체이며 해당 객체의 함수 호출을 사용하려면
    반드시 given+doReturn/willReturn 같은 stubbing 작업을 해줘야한다!
     
    Spring Context와 연관없이 순수하게 테스트를 하기 위해 가짜 객체를 생성하는 역할
    (그래서 Spring Boot의 어노테이션이 아니라 Mockito의 어노테이션이다!!)
     
    보통 단위테스트를 할때, 테스트 하고자하는 객체에만 집중하기 위해
    이외의 것들은 Mock로 선언해서 사용함
     
    Junit5에서는 Mockito를 통한 테스트를 진행하기 때문에
    테스트 클래스에서 해당 여부를 표시해주는 @ExtendWith 정보가 필요함

    @ExtendWith(MockitoExtension.class)
    public class ZipbobServiceTest {
        
        @InjectMocks
        private ZipbobService zipbobService;
    
        @Mock
        private ZipbobRepository zipbobRepository;
    
    }

     

    @ExtendWith(MockitoExtension.class)
    class AuthServiceTest {
        
        @InjectMocks
        private AuthService authService;
        
        @Mock
        private OAuthClient oAuthClient;
    
        @Mock
        private JwtProvider jwtProvider;
        
    }

     


    [@Spy]

     
    @Spy로 만든 mock 객체는 진짜 객체이고 메소드 실행 시
    stubbing을 하지 않으면 기존 객체의 로직을 실행한 값을,
    stubbing을 한 경우에는 given 값을 리턴한다

    즉 테스트에 쓰일 빈 객체를 주입하고 싶긴 한데, 해당 빈 객체가 실제로 동작하게끔 하고 싶으면 @Spy로 해주면 된다.

    @Spy는 실제로 자신의 코드대로 돌아가기 때문에 given으로 stubbing을 안해줘도 된다!

     

    'TDD' 카테고리의 다른 글

    [TDD] @Spy  (0) 2024.09.01
    [TDD] @Mock vs @MockBean  (1) 2024.08.31
    [TDD] @WebMvcTest vs MockMvcBuilders.standaloneSetup  (0) 2024.08.31
    [TDD] Spring Boot 테스트 종류  (1) 2024.08.31
    [TDD] H2Database  (1) 2024.02.13