Java Spring 테스트 코드

BackEnd_Ash.log·2023년 7월 27일
0

자바스터디

목록 보기
18/19
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

public class ProviderLoginTest {

    @Mock
    private UserRepository userRepository;

    @Mock
    private SecurityService securityService;

    @Mock
    private ProviderService providerService;

    @Test
    public void testLoginProvider() {
        // Test code goes here
    }
}

@Mock 어노테이션이 UserRepository와 SecurityService 인스턴스를 생성하고, @InjectMocks 어노테이션은 이러한 Mock 객체를 ProviderService 인스턴스에 주입합니다.
이로 인해, 테스트를 수행하는 동안 UserRepository와 SecurityService는 Mock 인스턴스가 되고, 이들의 동작은 Mockito를 통해 제어됩니다.

이렇게 설정한 후에는 이전에 작성했던 Mockito.when()과 같은 호출로 Mock 객체의 동작을 설정할 수 있습니다.

Mock 과 InjectMocks 차이점

@Mock@InjectMocks는 Mockito에서 제공하는 어노테이션이며, 둘 간에는 명확한 차이점이 있습니다.

@Mock은 간단히 말해 테스트에서 사용할 모의 객체(mock object)를 생성하는 데 사용됩니다. 이렇게 생성된 모의 객체는 실제 객체와 동일한 API를 가지지만, 그 동작은 개발자가 테스트 내에서 제어합니다. 이는 특정 메소드의 결과를 테스트하거나, 특정 메소드가 호출되었는지 검증하는 등의 용도로 사용됩니다.

그러나 @Mock으로 생성된 객체는 모의 객체이므로 그 안에 있는 의존성들은 채워지지 않습니다. 즉, @Mock으로 생성한 ProviderService 객체는 내부에서 사용하는 UserRepositorySecurityService 등의 의존성이 주입되지 않습니다.

반면에, @InjectMocks는 Mockito가 @Mock이나 @Spy 어노테이션이 붙은 객체를 해당 객체의 필드로 주입(inject)해줍니다. 즉, @InjectMocks를 사용하면 ProviderService의 내부 의존성인 UserRepository와 SecurityService에 @Mock으로 생성한 모의 객체가 주입되어, 실제 코드와 유사한 상황에서 테스트를 진행할 수 있게 됩니다.

따라서, 당신이 질문에서 언급한 @Mock ProviderService providerService; 코드에서 ProviderService는 모의 객체지만, 그 안의 UserRepositorySecurityServicenull일 것입니다. 이 코드가 "동작"한다는 것은, ProviderService 객체가 성공적으로 생성되었으며 그 메소드를 호출할 수 있음을 의미하지만, 그 메소드 내부에서 UserRepositorySecurityService를 사용하려고 하면 NullPointerException이 발생할 것입니다.

만약 ProviderService의 메소드가 UserRepositorySecurityService를 사용하지 않는다면, @Mock ProviderService providerService; 코드만으로도 테스트가 잘 수행될 수 있습니다. 그러나 일반적으로 서비스 계층의 메소드는 내부의 다른 컴포넌트들을 사용하기 때문에, 대부분의 경우 @InjectMocks를 사용해야 합니다.

예를들면

@InjectMocks를 사용하는 것은 테스트하고자 하는 클래스가 다른 클래스를 의존하고 있고, 이를 모의 객체로 대체하여 테스트하고 싶을 때 사용합니다.

예를 들어, ProviderService 클래스가 UserRepositorySecurityService를 사용하고 있고 이들을 테스트에서는 모의 객체로 사용하고 싶다면, 다음과 같이 사용합니다:

@Mock
private UserRepository userRepository;

@Mock
private SecurityService securityService;

@InjectMocks
private ProviderService providerService;

이렇게 하면, ProviderService에 대한 테스트에서는 UserRepositorySecurityService@Mock으로 선언된 모의 객체로 대체되어 사용됩니다.

반대로 SecurityService 클래스가 ProviderService를 사용하고 있고, 이를 모의 객체로 대체하여 SecurityService의 테스트를 하고 싶다면 다음과 같이 사용할 수 있습니다:

@Mock
private ProviderService providerService;

@InjectMocks
private SecurityService securityService;

이렇게 하면, SecurityService의 테스트에서 ProviderService@Mock으로 선언된 모의 객체로 대체되어 사용됩니다.

즉, @InjectMocks를 사용하는 클래스는 테스트 대상 클래스이며, 그 클래스가 사용하는 다른 클래스들은 @Mock이나 @Spy로 선언하여 모의 객체로 사용하게 됩니다. 이렇게 하면, 테스트 대상 클래스를 다른 클래스로부터 독립적으로 테스트할 수 있습니다.

profile
꾸준함이란 ... ?

0개의 댓글