programing

스프링 부트의 유닛 테스트 또는 통합 테스트

kingscode 2023. 7. 20. 22:59
반응형

스프링 부트의 유닛 테스트 또는 통합 테스트

.Spring Boot그리고 시험이 언급된 방식에 혼란을 겪었습니다.

를 사용하는 테스트에 언급합니다.@WebMvcTest서의주석으로 주석을 .Unit Test반면에 어떤 사람들은 그것을 라고 부릅니다.Integration Test어떤 것이 정확한지 잘 모르겠습니다.

됩니다.@DataJpaTest.

다음 두 가지 테스트가 애플리케이션에 작성되어 있습니다. 하나는 컨트롤러용이고 다른 하나는 저장소용입니다.

저는 두 가지 모두에 대해 몇 가지 질문이 있습니다.안내 부탁드립니다.

사용자 컨트롤러Test.java

@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;
    @MockBean
    private UserRepository userRepository;

    @Test
    public void signUp() throws Exception {
        this.mockMvc.perform(get("/signup")).andExpect(status().isOk());
    }

}

사용자 리포지토리 Test.java

@RunWith(SpringRunner.class)
@DataJpaTest
public class UserRepositoryTest {

    @Autowired
    private TestEntityManager entityManager;
    @Autowired
    private UserRepository userRepository;

    @Test
    public void whenFindByName_thenReturnEmployee() {
        // given
        User u = new User();
        u.setName("ab");
        u.setEmail("ab@cd.com");
        entityManager.persistAndFlush(u);
        // when
        Optional<User> user = userRepository.findById(1L);
        // then
        assertTrue(user.isPresent());
    }

}

제 질문은 다음과 같습니다.

  1. 주석을 실행합니까?@WebMvcTest, @DataJpaTest또는@SpringBootTest시험의합니다.Unit또는Integration )의 입니까?@MockBean그것을 결정하는 테스트 내에서?
  2. 라고 가정하면,UserControllerTest.java 것은 테스트입니다.userRepository와의 관계.@MockBean private UserRepository userRepository에 면에반에서는UserRepositoryTest.java우리는 그것을 자동 배선하고 있습니다.@Autowired private UserRepository userRepository 왜요? 왜요?

유닛 테스트를 하는데 스프링이 왜 필요합니까?스프링 컨텍스트를 시작할 필요 없이 Mockito만 사용할 수 있습니다.이에 대한 자세한 내용은 https://reflectoring.io/unit-testing-spring-boot/ 을 참조하십시오.

또한 @Mock Bean을 사용하는 것에 관해서는 저에게 매우 혼란스럽습니다!그것은 유닛으로 간주됩니까, 아니면 통합 테스트로 간주됩니까?제 생각에는, 우리도 조롱당한 콩을 사용하고 있지만, 우리는 여전히 스프링 컨텍스트 내에서 실행하고 있으며, 저에게 이것은 통합 테스트입니다(단위 테스트는 실행에 스프링 컨텍스트가 필요하지 않기 때문에).브랜든이 언급한 사이트와 동일한 사이트는 @MockBean을 통합 테스트 https://www.baeldung.com/java-spring-mockito-mock-mockbean 로 간주합니다.

위 사이트의 이미지

Brandon 응답: "통합 테스트에는 조롱이 포함되어서는 안 되며 두 가지 유형의 테스트를 별도로 실행해야 합니다."

컨트롤러에서 DB에 이르기까지 api를 테스트하고 다른 시스템(예: 카프카 또는 외부 마이크로서비스)을 제외하려면 어떻게 해야 합니까?어떻게 이를 달성하시겠습니까?당신은 @Mock Bean이 꼭 필요합니다.이것은 콩을 조롱했지만 통합 테스트입니다.

요약하자면(내 경험에 근거하여 그리고 며칠 동안 많은 모순되는 정보를 검색하고 읽은 후).제 의견은 이렇습니다.

  • 유닛 테스트에 스프링을 사용하는 것은 가급적 피하고 Mockito 또는 스프링 컨텍스트가 필요 없는 다른 프레임워크를 사용하십시오.예를 들어 일부 계산 로직을 테스트하기 위해 서비스 클래스에 대한 테스트를 작성할 때 스프링 컨텍스트가 필요하지 않으며 이는 PURE 단위 테스트입니다.
  • 우리는 여전히 컨트롤러 클래스에 대한 PURE 단위 테스트를 작성할 수 있습니다.컨트롤러의 메소드를 호출한 다음 이러한 메소드가 예상대로 수행되었다고 주장하면 됩니다(예: 올바른 매개 변수로 올바른 기본 메소드 호출 등).기본적으로 서비스 클래스에 대한 단위 테스트를 작성할 때와 동일합니다.(다음 유형의 테스트에서 이미 다루어진 경우에는 이러한 테스트가 필요하지 않을 수도 있습니다.)
  • 우리는 여전히 아피스에 대한 순수 단위 테스트를 스프링 컨텍스트 없이 작성할 수 있습니다.여기에 설명되어 있습니다.저는 노력했고 그것은 저에게 효과가 있었습니다.제가 게시물 끝에 코드를 붙여 놓겠습니다.
  • 스프링 컨텍스트에서 테스트를 실행할 때는 @MockBean을 사용하는 경우에도 통합 테스트로 간주됩니다.예를 들어 컨트롤러에서 DB까지 API를 테스트하고 다른 시스템(예: 카프카, 이메일 또는 기타 외부 마이크로서비스)은 제외합니다.어떻게 이를 달성할 수 있을까요?우리는 @Mock Bean이 꼭 필요합니다.이것은 일부 조롱당한 콩을 사용하더라도 통합 테스트입니다.
  • 생각하기에 가장 혼란스러운 부분질문의 UserControllerTest처럼 스프링만을 사용하여 api 레이어를 테스트할 때입니다(즉, api를 호출하여 올바른 상태 코드와 응답 형식을 반환하도록 하는 것입니다).그것은 유닛 테스트로 간주됩니까, 아니면 통합 테스트로 간주됩니까?단위 테스트를 실행하는 데 스프링 컨텍스트가 필요하지 않기 때문에 단위가 아닙니다.실제로는 단위 테스트와 통합 테스트 사이에 있습니다.이 소스는 이 개념을 매우 잘 설명합니다. https://blog.marcnuri.com/mockmvc-spring-mvc-framework/ (더 구체적으로 MockMvc 독립 실행형 설정) 그래서, 제 생각에, 이 테스트들을 어디에 둘지는 (유닛 테스트 폴더, 통합 테스트 폴더, 별도의 폴더) 팀으로 거슬러 올라갑니다.또한 동일한 클래스에 대한 순수 단위 테스트 또는 순수 통합 테스트와 혼동을 피하기 위해 좋은 명명 규칙을 사용해야 합니다.제가 본 바로는 대부분의 팀들이 유닛 테스트를 고려하지만, 그게 최선의 방법인지는 잘 모르겠습니다!

    //unit test to call an api using MockMvc and mockito only
    @RunWith(MockitoJUnitRunner.class)
    public class UserControllerTest {
    
    private MockMvc mockMvc;
    @Mock
    UserService userService;
    @InjectMocks
    UserController controllerUnderTest;
    
    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.standaloneSetup(controllerUnderTest).build();
    }
    
    @Test
    public void testGetUser() throws Exception {
    
        //given:
        when(userService.getUser(.......)).thenReturn(....);
    
        //when:
        String url = "http://localhost:8081/api/ ....your url";
    
        //then:
        this.mockMvc.perform(get(url)).andDo(print()).andExpect(status().isOk());
    }
    

    }

그게 도움이 되길 바라며, 제가 그것 때문에 많이 힘들었기 때문에 더 좋은 의견이 있으면 알려주세요 :)

유닛 테스트는 실행이 시작되기 전에 통합 테스트가 Spring 웹 컨텍스트 부트스트랩을 테스트하는 동안 독립적으로 실행됩니다.

유닛 테스트

독립적으로 실행하려면 테스트 중인 클래스를 기준으로 종속성을 조롱해야 하는 경우가 있습니다.이를 통해 서비스 또는 도메인 계층의 오버헤드에 대해 걱정할 필요 없이 매우 구체적인 테스트 사례를 엔드 투 엔드로 테스트할 수 있습니다.따라서 Mockito 또는 보다 구체적으로, Mockito.mock() 메서드를 사용하여 객체 클래스를 모킹하고 @MockBean과 같은 웹 컨텍스트의 객체를 대체하지 않습니다.

통합 테스트

반면, 통합 테스트는 데이터베이스와 같은 애플리케이션의 여러 계층을 통합하는 데 중점을 둡니다.데이터베이스와 관련하여 대부분의 사람들은 도메인 계층/저장소를 테스트하기 위해 H2와 같은 메모리 내 데이터베이스를 사용합니다.통합 테스트에는 조롱이 포함되지 않아야 하며 두 가지 유형의 테스트를 별도로 실행해야 합니다.이것은 통합 테스트에 조롱이 포함될 수 없다는 뜻은 아니지만, 조롱된 종속성을 포함하는 응용 프로그램의 다양한 계층을 테스트하는 분리된 단위 테스트가 이미 있기 때문에 일반적이지 않습니다!

E2E 테스트

애플리케이션을 엔드 투 엔드로 테스트하는 경우 적절한 정리를 통해 데이터 이외의 다른 데이터를 조롱하지 않는 것이 좋습니다.오이와 같은 테스트 프레임워크는 엔드 투 엔드 테스트에 매우 적합합니다.이미 그런 유형의 테스트에 대한 단위 테스트가 있는데 왜 다른 계층을 조롱합니까!

리소스: https://www.baeldung.com/spring-boot-testing 및 https://www.baeldung.com/java-spring-mockito-mock-mockbean

언급URL : https://stackoverflow.com/questions/54658563/unit-test-or-integration-test-in-spring-boot

반응형