Spring test

์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ๋Š” ๊ธฐ๋ณธ์ ์ธ ํ…Œ์ŠคํŠธ ์Šคํƒ€ํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์Šคํƒ€ํ„ฐ์— ์›ฌ๋งŒํ•œ ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ๋ญ‰์ณ๋†“์•„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • spring-boot-test

  • spring-boot-test-autoconfigure

์œ„ ๋‘๊ฐœ ๋ชจ๋“ˆ์ด ํ…Œ์ŠคํŠธ ๊ด€๋ จ ์ž๋™ ์„ค์ • ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ , ์ผ๋ฐ˜์ ์œผ๋กœ spring-boot-starter-test๋กœ ๋‘ ๋ชจ๋“ˆ์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค.

dependencies {
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

๋‹จ์œ„ ํ…Œ์ŠคํŠธ(JUnit)

Spring Boot์—์„œ JUnit5๋ฅผ ์ด์šฉํ•ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ธฐ ์ „์— ๊ธฐ๋ณธ์ ์ธ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃจ๊ณ  ๋„˜์–ด๊ฐˆ ๊ฒƒ์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ(Unit Test) ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ 5๊ฐ€์ง€ ์›์น™์„ ๊ฐ•์กฐํ•œ๋‹ค.

  • Fast : ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์ผ์€ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋ฉด ์•ˆ๋œ๋‹ค.

  • Independent : ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰์ด ๋˜์–ด์•ผํ•œ๋‹ค.

  • Repeatable : ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค.

  • Self Validation : ๋ฉ”๋‰ด์–ผ ์—†์ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋งŒ ์‹คํ–‰ํ•ด๋„ ์„ฑ๊ณต, ์‹คํŒจ ์—ฌ๋ถ€๋ฅผ ์•Œ ์ˆ˜ ์žˆ์–ด์•ผํ•œ๋‹ค.

  • Timely : ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค.

Junit

Junit์€ Java์˜ ๋‹จ์œ„ ํ…Œ์ŠคํŒ… ๋„๊ตฌ์ด๋‹ค.

  • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ Framework์ค‘ ํ•˜๋‚˜

  • ๋‹จ์ •๋ฌธ์œผ๋กœ Test Case ์ˆ˜ํ–‰๊ฒฐ๊ณผ๋ฅผ ํŒ๋ณ„ํ•œ๋‹ค.

  • Annotation์œผ๋กœ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.

Dependencies

spring boot 2.2.0 ์ดํ›„ ๋ฒ„์ „์—์„œ๋Š” Junit5๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค. Junit5๋Š” Java8 ๋ถ€ํ„ฐ ์ง€์›ํ•˜๋ฉฐ, ์ด์ „ ๋ฒ„์ „์œผ๋กœ ์ž‘์„ฑ๋œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—ฌ๋„ ์ปดํŒŒ์ผ์ด ์ง€์›๋œ๋‹ค.

SpringBoot 2.2.0 ์ด์ „ ๋ฒ„์ „์—์„œ junit5 ์„ค์ •

  • maven

    <!-- spring boot test junit5 ์‚ฌ์šฉ exclusion์„ ํ†ตํ•ด junit4์—์„œ ์ฝ”๋“œ ์‹คํ–‰์‹œ ์‚ฌ์šฉํ•˜๋Š” vintage-engine ์˜ˆ์™ธ์ฒ˜๋ฆฌ-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <groupId>org.junit.vintage</groupId>
          <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    
    <!-- ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์— ํ•„์š”ํ•œ junit-jupiter-api ๋ชจ๋“ˆ๊ณผ ํ…Œ์ŠคํŠธ ์‹คํ–‰์„ ์œ„ํ•œ junit-jupiter-engine ๋ชจ๋“ˆ ํฌํ•จ -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
    </dependency>
  • gradle

    testImplementation ('org.springframework.boot:spring-boot-starter-test') {
    	exclude module: 'junit'
    }
    testImplementation 'org.junit.jupiter:junit-jupiter-api'
    testRuntimeOnly'org.junit.jupiter:junit-jupiter-engine'

Test ๋‹จ์œ„

์„ค๋ช…Bean

@SpringBootTest

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ, ์ „์ฒด

Bean ์ „์ฒด

@WebMvcTest

๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Mvc ํ…Œ์ŠคํŠธ

MVC ๊ด€๋ จ๋œ Bean

@DataJpaTest

๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Jpa ํ…Œ์ŠคํŠธ

JPA ๊ด€๋ จ Bean

@RestClientTest

๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Rest API ํ…Œ์ŠคํŠธ

์ผ๋ถ€ Bean

@JsonTest

๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Json ํ…Œ์ŠคํŠธ

์ผ๋ถ€ Bean

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;

/**
 * ExtendWith : JUnit5 ํ™•์žฅ ๊ธฐ๋Šฅ
 *
 */
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = T2020AprilApplicationTests.class)
@ActiveProfiles("test")
@Transactional
public class T2020AprilApplicationTests {

	@Test
	void contextLoads() {
	}

}
  • @SpringBootTest ๋Š” ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ์ ์ธ Spring Boot Test ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. ์—ฌ๋Ÿฌ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋‚˜์˜ ํ†ตํ•ฉ๋œ ํ…Œ์ŠคํŠธ๋กœ ์ˆ˜ํ–‰ํ•  ๋•Œ ์ ํ•ฉํ•˜๋‹ค.

    • @SpringBootApplication ์ด ๋ถ™์€ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ฐพ์•„ context๋ฅผ ์ฐพ๋Š”๋‹ค.

    • ์‹ค์ œ ๊ตฌ๋™๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋˜‘๊ฐ™์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ๋ฅผ ๋กœ๋“œํ•ด ํ…Œ์ŠคํŠธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๊ณ  ์‹ถ์€ ํ…Œ์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์„ค์ •๋œ ๋นˆ์„ ๋ชจ๋‘ ๋กœ๋“œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ทœ๋ชจ๊ฐ€ ํด์ˆ˜๋ก ๋Š๋ ค์ง„๋‹ค.

    • properties : ํ…Œ์ŠคํŠธ ์‹คํ–‰๋˜๊ธฐ์ „ {key,value} ํ˜•์‹์œผ๋กœ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

      @SpringBootTest(properties = {"property.value= propertyTest"})
    • value : ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „ ์ ์šฉํ•  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.

      @SpringBootTest(value= "value=test")
    • classes : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ์— ๋กœ๋“œํ•  ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณ„๋„๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด, @SpringBootApplication or @SpringBootConfiguration ์„ ์ฐพ์•„์„œ ๋กœ๋“œํ•œ๋‹ค.

      @SpringBootTest(classes= {SpringBootTestApplication.class})
  • @ExtendWith ๋Š” ํ™•์žฅ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค.

    • JUnit5์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์˜ ์ƒ๋‹น์ˆ˜๊ฐ€ ์ด ๊ธฐ๋Šฅ์œผ๋กœ ์ง€์›๋˜๊ณ  ์žˆ๋‹ค.

    • ์‹ค์ œ ๊ธฐ๋Šฅ์ด ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด์„œ ์‹คํ–‰๋œ๋‹ค.

    • JUnit4์—์„œ RunWith์™€ ์œ ์‚ฌํ•˜๋‹ค.

  • @ActiveProfiles ๋Š” ์›ํ•˜๋Š” ํ”„๋กœํŒŒ์ผ ํ™˜๊ฒฝ ๊ฐ’์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • @Transactional : ํ…Œ์ŠคํŠธ๋ฅผ ๋งˆ์น˜๊ณ  ๋‚˜์„œ ์ˆ˜์ •๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กค๋ฐฑ๋œ๋‹ค.

Mock ๊ฐ์ฒด

ํ…Œ์ŠคํŠธ์‹œ ๋ชจ๋“  ๊ฐ€๋ณ€์ ์ธ ์˜์—ญ(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„, ๋ฉ”์‹œ์ง• ๋ฏธ๋“ค์›จ์–ด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค)์€ ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šฐ๋ฉฐ, ์ƒํ˜ธ์ž‘์šฉ์‹œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ๋‹ค.

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ํ…Œ์ŠคํŠธํ•  ๋ชฉ์ ์ด๋ผ๋ฉฐ, ํ•ด๋‹น ๋กœ์ง์ด ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋‹ค์–‘ํ•œ ์˜์กด์„ฑ์„ ๋ชจ๋‘ ํ…Œ์ŠคํŠธํ•  ํ•„์š”๋Š” ์—†๋‹ค. Mock ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ๋Œ€์ฒดํ•˜๊ณ , ์™ธ๋ถ€ ์˜์กด์„ฑ์˜ ์˜ํ–ฅ ์—†์ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

Stub์€ ํ…Œ์ŠคํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๊ตฌํ˜„์ฒด์ด๋‹ค. (Stub์€ Mock ๊ฐ์ฒด๊ฐ€ ์•„๋‹˜)

Mockito

Mockito๋Š” ํ”„๋ก์‹œ ๊ธฐ๋ฐ˜์˜ Mock๊ฐ์ฒด ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ํ‘œํ˜„๊ตฌ๋ฌธ๊ณผ ๋งŽ์€ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•œ๋‹ค. Mockito๋ฅผ ์‚ฌ์šฉํ•ด ํ™•์ธ์ด ํ•„์š”ํ•œ ๋™์ž‘์„ ๋ชจํ‚นํ•ด ์ค‘์š”ํ•œ ๋™์ž‘๋งŒ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค.

MockMvc Test

MockMvc ๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์˜๋ฏธํ•˜๋Š” ๊ฐ์ฒด๋กœ์„œ ์›น์—์„œ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ํž˜๋“  Controller ํ…Œ์ŠคํŠธ๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•ด์ค€๋‹ค. ๋˜ํ•œ ์‹œํ๋ฆฌํ‹ฐ ํ˜น์€ ํ•„ํ„ฐ๊นŒ์ง€ ์ž๋™์œผ๋กœ ํ…Œ์ŠคํŠธํ•ด ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€/์‚ญ์ œ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

@WebMvcTest๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Book.java

    package com.example.boot.domain;
    
    import lombok.Builder;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    
    import java.time.LocalDateTime;
    
    @NoArgsConstructor
    @Getter
    public class Book {
        private Integer idx;
        private String title;
        private LocalDateTime publishedAt;
    
        @Builder
        public Book(String title, LocalDateTime publishedAt){
            this.title = title;
            this.publishedAt = publishedAt;
        }
    }
  • Service

    package com.example.boot.service;
    
    import com.example.boot.domain.Book;
    
    import java.util.List;
    
    public interface BookService {
        List<Book> getBookList();
    }
  • Controller

    package com.example.boot.controller;
    
    import com.example.boot.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Controller
    public class BookController {
    
      @Autowired
      private BookService bookService;
    
      @GetMapping("/books")
      public String getBookList(Model model) {
          model.addAttribute("bookList", bookService.getBookList());
          return "book";
      }
    }
  • test

    package com.example.boot;
    
    import com.example.boot.controller.BookController;
    import com.example.boot.domain.Book;
    import com.example.boot.service.BookService;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
    import org.springframework.boot.test.mock.mockito.MockBean;
    import org.springframework.test.web.servlet.MockMvc;
    
    import static org.hamcrest.Matchers.contains;
    import static org.mockito.BDDMockito.given;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
    
    import java.time.LocalDateTime;
    import java.util.Collections;
    
    @WebMvcTest(BookController.class)
    public class BookControllerTest {
    
        @Autowired
        private MockMvc mockMvc;
    
        @MockBean
        private BookService bookService;
    
        @Test
        public void Book_MVC_TEST() throws Exception {
            Book book = new Book("Spring Boot Book", LocalDateTime.now());
            given(bookService.getBookList()).willReturn(Collections.singletonList(book));
            mockMvc.perform(get("/books"))
                    .andExpect(status().isOk())
                    .andExpect(view().name("book"))
                    .andExpect(model().attributeExists("bookList"))
                    .andExpect(model().attribute("bookList",contains(book)));
        }
    
    }
  • @WebMvcTest(BookController.class) : ํ…Œ์ŠคํŠธํ•  ์ปจํŠธ๋กค๋Ÿฌ๋ช…์„ ๋ช…์‹œํ•ด์ค€๋‹ค.

  • ์—ฌ๊ธฐ์„œ @Service์€ @WebMvcTest์˜ ์ ์šฉ ๋Œ€์ƒ์ด ์•„๋‹ˆ๋‹ค. BookService ์ธํ„ฐํŽ˜์ด์Šฌ๋ฅด ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด๋Š” ์—†์ง€๋งŒ, @MockBean์„ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•ด ์ปจํŠธ๋กค๋Ÿฌ ๋‚ด๋ถ€์˜ ์˜์กด์„ฑ ์š”์†Œ๋ฅผ ๊ฐ์ž ๊ฐ์ฒด๋กœ ๋Œ€์ฒด ํ–ˆ๋‹ค. MockBean์€ ์‹ค์ œ ๊ฐ์ฒด๋Š” ์•„๋‹ˆ์ง€๋งŒ ์‹ค์ œ ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

    • given(bookService.getBookList()).willReturn(Collections.singletonList(book)); : ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด given()์„ ์‚ฌ์šฉํ•ด ๋ฉ”์„œ๋“œ ์‹คํ–‰์— ๋Œ€ํ•œ ๋ฐ˜ํ™˜๊ฐ’์„ ๋ฏธ๋ฆฌ ์„ค์ •ํ–ˆ๋‹ค.

  • ๊ทธํ›„ andExpect()๋กœ ์˜ˆ์ƒ ๊ฐ’์ด ๋‚˜์˜ค๋Š”์ง€์— ๋Œ€ํ•ด์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค.

๋งŒ์•ฝ ๊ธฐ๋ณธ์„ค์ •๋งŒ ํ•„์š”ํ•˜๋‹ค๋ฉด @AutoConfigureMockMvc ์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

@SpringBootTest
@AutoConfigureMockMvc
public abstract class AbstractControllerTest {
    
	@Autowired
	protected MockMvc mockMvc;

}

ํ•˜์ง€๋งŒ AutoConfig๋กœ ์„ค์ •์„ ํ•˜๋ฉด Customํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง„๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” MockMvcBuilders๋ฅผ ํ™œ์šฉํ•ด MockMvc ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์—ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ณตํ†ต ์ถ”์ƒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

/**
 * ํ…Œ์ŠคํŠธ์‹œ ํ•„์š”ํ•œ ์ปค์Šคํ…€ ๊ณตํ†ต ์„ค์ • ์ถ”์ƒ ํด๋ž˜์Šค
 */
@SpringBootTest
public abstract class AbstractControllerTest {
	
	protected MockMvc mockMvc;
	
	abstract protected Object controller();

	@BeforeEach
	private void setup() {
		mockMvc = MockMvcBuilders.standaloneSetup(controller()) 						 // ๊ธฐ๋ณธ์„ค์ • 
			.addFilter(new CharacterEncodingFilter(StandardCharsets.UTF_8.name(), true)) // ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰์‹œ ํ•œ๊ธ€ ๊นจ์ง ๋ฐฉ์ง€
			.alwaysDo(print())															 // ํ•ญ์ƒ ์ฝ˜์†” ์ถœ๋ ฅ
			.build();
		
	}
}

์ด์ œ ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ Controller ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

/**
 * ํ…Œ์ŠคํŠธ์‹œ ํ•„์š”ํ•œ ๊ณตํ†ต ์„ค์ • ์ถ”์ƒ ํด๋ž˜์Šค(AbstractController) ์ƒ์†
 * PaymentGatewayController ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค
 * TestMethodOrder : OrderAnnotaion๊ธฐ์ค€์œผ๋กœ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ ์ˆ˜ํ–‰  
 */
@TestMethodOrder(OrderAnnotation.class)
public class PaymentGatewayControllerTest extends AbstractControllerTest {

	private static String[] pmtCodeArr = {"P0001", "P0001", "P0002", "P0003", "P0003", "P0004", "P0005"}; // pmtCode ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด
	private static String[] mbrIdArr = {"0000000345", "0000000911", "0000000602"}; 	// mbrId ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด

	
	@Autowired
	PaymentGatewayController paymentGatewayController;
	
	
	/**
	 * @return ํ…Œ์ŠคํŠธํ•  paymentController ์ธ์Šคํ„ด์Šค
	 */
	@Override
	protected Object controller() {
		// TODO Auto-generated method stub
		return paymentGatewayController;
	}
 	
	
	/**
	 * Test method for {@link com.example.test.controller.PaymentGatewayController#approve(java.lang.String, java.lang.String, java.lang.String, long)}.
	 * ๊ฒฐ์ œ ์Šน์ธ ์š”์ฒญ ํ…Œ์ŠคํŠธ
	 * ๊ฐ๊ฐ mbrId๋ณ„๋กœ pmtCodeArr ๋ฐ์ดํ„ฐ๋กœ ์ƒ์„ฑ
	 * ์ด๋–„, pmtType์€ null๋กœ ๋ณด๋‚ธ๋‹ค.(์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋„๋ก) 
	 * Order annotation์€ ํ…Œ์ŠคํŠธ ์‹คํ–‰์ˆœ์„œ ์ง€์ •
	 */
	@Test
	@Order(1)
	void testApprove() {
	     try {
	    	 
	    	 for(int i=0;i<7;i++) {
	    		 for(String mbrId : mbrIdArr) {
	    			 MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
	    				
	    			 params.add("mbrId", mbrId);
	    			 params.add("pmtCode", pmtCodeArr[i]);
	    			 params.add("pmtType", "");
	    			 params.add("pmtAmt", "157400");
	    			 
             // curl -X POST "http://localhost:8080/api/pg/approve?mbrId=&pmtAmt=&pmtCode=" -H "accept: */*"
	    			 mockMvc.perform(post("/api/pg/approve")
	    					 			.contentType(MediaType.APPLICATION_JSON)
	    					 			.params(params))
	    			 					.andExpect(status().isOk()); // ์„ฑ๊ณต์—ฌ๋ถ€ ํ™•์ธ
	    		 }
	    	 }
	    	
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Test method for {@link com.example.test.controller.PaymentGatewayController#getRecentPaymentList(java.lang.String, java.lang.String, java.lang.Integer)}.
	 * ์ตœ๊ทผ ๊ฒฐ์ œ๋‚ด์—ญ๋ฆฌ์ŠคํŠธ ์กฐํšŒ ํ…Œ์ŠคํŠธ
	 * ๊ฐ๊ฐ member ๋ณ„๋กœ 10๊ฐœ์”ฉ ์กฐํšŒ
	 */
	@Test
	@Order(2)
	void testGetRecentPaymentList() {
		
		try {
			for(String mbrId : mbrIdArr) {
				MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
				params.add("mbrId", mbrId);
				params.add("size", "10");
				
        // curl -X GET "http://localhost:8080/api/pg/approve?mbrId=&pmtAmt=&pmtCode=" -H "accept: */*"
				mockMvc.perform(get("/api/pg/getRecentPaymentList")
						.params(params))
						.andExpect(status().isOk()) 							// ์ˆ˜ํ–‰๊ฒฐ๊ณผ ํ™•์ธ
				 		.andExpect(jsonPath("$[*]", hasSize(10))) 					// ๊ฐ ๋ฉค๋ฒ„๋ณ„ ๋ฆฌ์ŠคํŠธ ์ˆ˜ ํ™•์ธ 
				 		.andExpect(jsonPath("$[?(@.succYn =='Y')]", hasSize(9)))	// ์„ฑ๊ณต์—ฌ๋ถ€ ์„ฑ๊ณต(Y) 9๊ฐœ ํ™•์ธ
				 		.andExpect(jsonPath("$[?(@.succYn =='N')]", hasSize(1)));	// ์„ฑ๊ณต์—ฌ๋ถ€ ์‹คํŒจ(N) 1๊ฐœ ํ™•์ธ 
				
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 		
	}

	

}
  • @Test : ํ…Œ์ŠคํŠธ ๋Œ€์ƒ์„ ์ง€์ •

  • @Order : ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰ ์ˆœ์„œ ์ง€์ •

  • @TestMethodOrder(OrderAnnotation.class) : OrderAnnotation ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰

์ฐธ์กฐ

Last updated