๐Ÿ’ป
Albert's Til
GitHub
  • ๋งค์ผ๋งค์ผ ์กฐ๊ธˆ์”ฉ ์„ฑ์žฅํ•˜๊ธฐ
    • README
    • CS
      • Network
      • HTTP
        • NO-CACHE
      • ์˜ค๋ฅ˜ ์ฝ”๋“œ
      • ORM ๋„๊ตฌ
      • Design Pattern
        • CQRS Pattern
          • Event Sourcing and CQRS pattern
        • Builder Pattern
    • DB
      • MySQL
        • Timeline
        • Pagination
        • Index
        • Database Performance Optimization Strategies
        • B+ tree
        • MySQL Connectors VS MySQL Shell(Scripting) VS MySQL Workbench
        • MySQL Storage Engine Architecture
      • Normalization & Denormalization
      • JPA
        • @Transactional
        • Why JPA?
        • About JPA
        • N+1 Issue
        • Index
        • ElementCollection&CollectionTable
        • orphanRemoval
        • CascadeType
        • Use Subselect
        • Dynamic Instance Creation
        • Paging
        • Order
        • Spefication
        • mappedBy
      • MongoDB
        • ObjectId
      • Why MySQL?
      • ACID properties of transactions
      • Between JPA and JDBC
      • Identifiers in Hibernate/JPA
    • Java
      • Jackson de/serialize
      • Collections.singletonList() vs List.of()
      • Manage dependencies in Gradle
      • Logging Level
      • Bean Validation
      • JVM Internals
        • Threads
          • Frame
        • Shared Between Threads
          • Classloader
            • Class Loader Hierarchy
            • Loading Linking Initialization
      • Java Collection Framework
      • Annotation
      • Generic
      • ๋””๋ฏธํ„ฐ ๋ฒ•์น™
    • Spring
      • Caching
      • Spring Integration Overview
        • ThreadPollTaskExecutor
        • Messaging Bridge
        • Channel Adapter
        • Poller
        • Configuration and @EnableIntegration
        • Message Endpoints
        • Message Channels
      • HATEOAS
      • @Autowired vs Constructor Dependency Injection
      • Spring Security
        • JWT ํ† ํฐ ์‚ฌ์šฉํ•œ ์ธ๊ฐ€
        • OAuth 2 Login
        • OAuth 2 ์ธ์ฆ
        • ์ธ๊ฐ€
        • ์ธ์ฆ
        • PasswordEncoder
      • IoC Container
      • Filter,Interceptor,AOP,Argument Resolver
      • Spring Annotation
      • About Spring
    • Kafka
      • Error Channel
    • Infra
      • Scale Up || Scale Out
      • Docker
        • Dockerfile
        • Docker Hub Deploy
        • Command
      • Cloud ์œ ํ˜•
        • Infrastructure as a Service
        • Platform as a Service
        • Software as a Service
      • ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ
        • ์—”์ง„์—‘์Šค(Nginx)
      • ์ฝ”๋“œ ์ž๋™ ๋ฐฐํฌ
        • Technical
      • AWS EC2
        • PEM(Privacy Enhanced Mail) ํ‚ค
      • AWS RDS
      • AWS S3
    • CodeSquad
      • Spring Boot Project 1์ฃผ์ฐจ ํšŒ๊ณ 
      • Spring Boot Project 2์ฃผ์ฐจ ํšŒ๊ณ 
      • Spirng Boot Project 3์ฃผ์ฐจ ํšŒ๊ณ 
      • Spring Boot Project 4์ฃผ์ฐจ ํšŒ๊ณ 
    • Foody Moody ํ”„๋กœ์ ํŠธ
      • Query Performance Comparison
      • HeartCount Asynchronous Issue
      • DeferredResult
      • ResponseBodyEmitter
      • SseEmitter (Spring)
      • Server-Sent Events (SSE)
      • ๊ธฐ์ˆ  ์Šคํƒ ์ ์šฉ ์ด์œ 
      • NO-CACHE(HTTP)
      • Transactional
    • DDD
      • AggregateId
    • Test
      • RestAssured
    • Coding and Algorithmic Problems
      • 819. Most Common Word
      • 344. Reverse String
      • 125. Valid Palindrome
      • 937. Reorder Data in Log Files
    • Node
      • Async... Await...
      • Custom Transactional Decorator Challenger
    • Python
      • Python Basic Grammar
        • Comments and Input/Output
        • Variable
        • Data type
        • Operations and syntax
        • List,Tuple,Dictionary,Set
        • Function
        • Conditional statement
        • Loop
    • HTML
      • HTML Basic
      • HTML Basic Tags
      • HTML Form Tags
      • HTML Table Tags
    • CSS
      • CSS Basic
      • CSS Practice
Powered by GitBook
On this page
  • ์ƒํ™ฉ
  • MockMvc์˜ ํ•œ๊ณ„
  • ์˜ˆ์‹œ ์ฝ”๋“œ
  • ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
  • RestAssured์™€ Cucumber์˜ ๋น„๊ต
  • ๋‚ด๊ฐ€ ์„ ํƒํ•œ ๋ฐฉ๋ฒ•๊ณผ ์ด์œ 
  • ๊ฒฐ๊ณผ

Was this helpful?

  1. ๋งค์ผ๋งค์ผ ์กฐ๊ธˆ์”ฉ ์„ฑ์žฅํ•˜๊ธฐ
  2. Test

RestAssured

์ƒํ™ฉ

  • ํŒ€ ์›น ์„œ๋น„์Šค API ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ํ•˜๋ฉด์„œ Spring MockMvc๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด์™”์Šต๋‹ˆ๋‹ค.

MockMvc์˜ ํ•œ๊ณ„

  • MockMvc๋Š” Spring MVC์˜ ์ปจํŠธ๋กค๋Ÿฌ ํ…Œ์ŠคํŠธ์— ํŠนํ™”๋˜์–ด ์žˆ์ง€๋งŒ, ์‹ค์ œ HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต์˜ ํ๋ฆ„์„ ์™„์ „ํžˆ ๋ชจ๋ฐฉํ•˜์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค.

  • ๋ณต์žกํ•œ ์„ค์ •๊ณผ ์ƒ๋Œ€์ ์œผ๋กœ ๋‚ฎ์€ ๊ฐ€๋…์„ฑ์œผ๋กœ ์ธํ•ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ

@Sql(statements = "insert into organization (title) values ('eojjeogojeojjeogo')")
@DisplayName("๋งˆ์ผ ์Šคํ†ค ์ˆ˜์ • ์š”์ฒญํ•˜๋ฉด 200 ์ฝ”๋“œ๋ฅผ ์‘๋‹ตํ•œ๋‹ค")
@Test
void updateMilestone() throws Exception {
        // given
        long milestoneId = milestoneService.create(ORGANIZATION_TITLE, createMileStoneRequest);
        MilestoneRequest changedMilestoneRequest = new MilestoneRequest(TEST_TITLE, TEST_DESCRIPTION,
                TEST_DUE_DATE);
        // when
        mockMvc.perform(patch("/api/" + ORGANIZATION_TITLE + "/milestones/" + milestoneId)
                        .content(objectMapper.writeValueAsString(changedMilestoneRequest))
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON)
                )
                // then
                .andDo(print())
                .andExpect(status().isOk());
}

๋งŒ์•ฝ์—์„œ milestoneService์˜ create์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ๋ณ€๊ฒฝ์„ ํ•˜๋ฉด ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋„ ๋Œ€์‘ํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  • MockMvc ๋Œ€์‹  RestAssured์™€ Cucumber๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ BDD ๋ฐฉ์‹์œผ๋กœ ๊ฐœ์„ ํ•˜๋ ค๊ณ  ๊ฒ€ํ† ํ–ˆ์Šต๋‹ˆ๋‹ค.

RestAssured์™€ Cucumber์˜ ๋น„๊ต

RestAssured์˜ ์žฅ์ 

  • ์‹ค์ œ HTTP ํ…Œ์ŠคํŠธ: RestAssured๋Š” ์‹ค์ œ HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ํ…Œ์ŠคํŠธํ•˜์—ฌ ์‹ค์ œ ํ™˜๊ฒฝ์— ๋” ๊ฐ€๊นŒ์šด ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ„๊ฒฐํ•˜๊ณ  ๋ช…ํ™•ํ•œ API: API ํ…Œ์ŠคํŠธ์— ์ตœ์ ํ™”๋œ ๊ตฌ๋ฌธ์„ ์ œ๊ณตํ•˜์—ฌ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€ ๊ด€๋ฆฌ๋ฅผ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

  • API ํ…Œ์ŠคํŠธ์— ํŠนํ™”: ๋ณต์žกํ•œ API ์š”์ฒญ ๋ฐ ๋ฐ์ดํ„ฐ ํฌ๋งท์„ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด API ํ…Œ์ŠคํŠธ์— ๋งค์šฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

given().
        config(RestAssured.config().xmlConfig(xmlConfig().declareNamespace("test", "http://localhost/"))).
when().
         get("/namespace-example").
then().
         body("foo.bar.text()", equalTo("sudo make me a sandwich!")).
         body(":foo.:bar.text()", equalTo("sudo ")).
         body("foo.test:bar.text()", equalTo("make me a sandwich!"));

Cucumber์˜ ์žฅ์ 

  • BDD ์ ‘๊ทผ๋ฒ•: Cucumber๋Š” ์ž์—ฐ ์–ธ์–ด๋กœ ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ž‘์„ฑํ•˜์—ฌ, ๋น„๊ธฐ์ˆ ์  ์ดํ•ด๊ด€๊ณ„์ž๋„ ํ…Œ์ŠคํŠธ ๊ณผ์ •์„ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํŒ€ ๋‚ด ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ ๊ฐ•ํ™”: BDD ์ ‘๊ทผ๋ฒ•์€ ๊ฐœ๋ฐœ์ž, ํ…Œ์Šคํ„ฐ, ๋น„์ฆˆ๋‹ˆ์Šค ์ดํ•ด๊ด€๊ณ„์ž ๊ฐ„์˜ ๋ช…ํ™•ํ•œ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์„ ์ด‰์ง„ํ•ฉ๋‹ˆ๋‹ค.

  • ์‚ฌ์šฉ์ž ์ค‘์‹ฌ์˜ ํ…Œ์ŠคํŠธ: ์‚ฌ์šฉ์ž์˜ ๊ฒฝํ—˜๊ณผ ์š”๊ตฌ์‚ฌํ•ญ์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์„ค๊ณ„ํ•˜๊ณ  ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Scenario: Breaker guesses a word
  Given the Maker has chosen a word
  When the Breaker makes a guess
  Then the Maker is asked to score

๋‚ด๊ฐ€ ์„ ํƒํ•œ ๋ฐฉ๋ฒ•๊ณผ ์ด์œ 

  • RestAssured๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ HTTP ํ…Œ์ŠคํŠธ๋ฅผ ํ…Œ์ŠคํŠธ ํ• ์ˆ˜ ์žˆ๊ณ  ๊ฐ„๊ฒฐํ•˜๊ณ  ๋ช…ํ™•ํ•œ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๊ณ  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์œ ์ง€ ๋ณด์ˆ˜๊ฐ€ ์‰ฝ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์—ฌ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

  • ํ…Œ์ŠคํŠธ Step๋ฅผ ํ•œ๊ธ€ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ฉํ•˜๊ณ  ํ…Œ์ŠคํŠธ์˜ ๊ฐ€๋…์„ฑ๋ฅด ํ–ฅ์ƒ๋˜์˜€๊ณ  ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์˜ ๋ณ€๊ฒฝ ๋”ฐ๋ผ ๋ณ€๊ฒฝ์ด ์ ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

@DisplayName("๋‚ด ๊ด€์‹ฌ์ƒํ’ˆ์— ๋‹ด์€ ํ›„, ํ•ด๋‹น ๊ด€์‹ฌ์ƒํ’ˆ ์‚ญ์ œ")
@Test
void shouldRemoveProductToInterestedProductsList() {
    ์ถœ๋ ฅ_ํ•„๋“œ_์ถ”๊ฐ€("member_removeLikeProduct", spec);

    // given
    var id = ์ƒํ’ˆ์„_๋“ฑ๋กํ•œ๋‹ค(ayaanAccessToken, 1).jsonPath().getString("id");
    ๊ด€์‹ฌ์ƒํ’ˆ์—_๋‹ด๋Š”๋‹ค(id, albertAccessToken);

    // when
    var response = ๊ด€์‹ฌ์ƒํ’ˆ์—_์ œ๊ฑฐํ•œ๋‹ค(id, albertAccessToken, spec);

    // then
    ๊ด€์‹ฌ์ƒํ’ˆ์€_๋‹ด์€_์‘๋‹ต_๊ฒ€์ฆ(response);
}

Last updated 1 year ago

Was this helpful?