
API๋ฅผ ๋ง๋ค๋ค๋ณด๋ฉด,
์
๋ ฅ๊ฐ์ ์ ํํ๊ณ ์ถ์ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํฉ๋๋ค.
์๋ฅผ๋ค๋ฉด,
public class Delivery {
private int id;
private String item;
private String user;
private LocalDateTime deliveryTime;
private LocalDateTime deliveryEndTime;
private DeliveryStatus status;
private Integer itemPrice;
private Integer deliveryCost;
}
์ด๋ฐ ๊ฐ์ฒด๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ด
์๋ค.
๊ทธ๋ฐ๋ฐ, id๊ฐ์ ๊ฒฝ์ฐ jpa์์ ๋ฒํธ๋ฅผ ์ ํด์ฃผ๊ณ ,
deliveryStatus๋ ํ์ฌ ๋ฐฐ๋ฌ์ ์งํ์ ๋ณด๊ณ ๊ฒฐ์ ๋๊ณ ,
deliveryCost๋ itemPrice์ ๊ฐ์ ๋ณด๊ณ ๊ฒฐ์ ํ๋ค๊ณ ๊ฐ์ ํด๋ณธ๋ค๋ฉด,
๋ ๊ฐ์ ์
๋ ฅ์ ๋ฐ์์๋ ์๋๋ ๊ฐ๋ค์
๋๋ค.
์๋ํ๋ฉด ์ธ๋ถ์์ ๊ทธ ๊ฐ๋ค์ ๊ฒฐ์ ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํด๋ด ์๋ค.
@Test
void create_Delivery() throws Exception {
Delivery delivery = Delivery.builder()
.id(100)
.item("book")
.user("klom")
.build();
Mockito.when(deliveryRepository.save(delivery)).thenReturn(delivery);
mockMvc.perform(post("/api/delivery/")
.accept(MediaTypes.HAL_JSON_VALUE)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsString(delivery))
)
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("id").value(Matchers.not(100)))
.andExpect(jsonPath("status").value(DeliveryStatus.READY))
.andExpect(jsonPath("deliveryCost").value(5000))
;
}
id๊ฐ์ด 100์
๋๋ค.
์ ํฌ๋ id๊ฐ์ ์๋์ผ๋ก ์ฆ๊ฐ๋๊ธฐ ์ํ๊ณ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ ์ฝ๋๋ 201๊ฐ ๋์์ผ ๋ฉ๋๋ค.
ํ์ง๋ง
๊ฒฐ๊ณผ๋ ํ
์คํธ ์คํจ์
๋๋ค.
๊ทธ๋ฌ๋ฉด ์ด๋ป๊ฒ ํด์ผ ๋ ๊น์?
๋ฐฉ๋ฒ์ ์ฌ๋ฌ๊ฐ์ง ์
๋๋ค.
์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์
@JsonIgnore์ด๋
ธํ
์ด์
์ ๋ถ์ด๋ฉด ํด๊ฒฐ๋๋ ๊ฒฝ์ฐ์
๋๋ค.
public class Delivery {
@Id
@GeneratedValue
private int id;
private String item;
private String user;
private LocalDateTime deliveryTime;
private LocalDateTime deliveryEndTime;
@JsonIgnore
private DeliveryStatus status;
private Integer itemPrice;
@JsonIgnore
private Integer deliveryCost;
}
id๋ null์ด ๋ฐ์ํด์ ์ผ๋จ ๋ถ์ด์ง ์์์ต๋๋ค;;
์ด๊ฒ์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ด๋ฐ ์ค๋ช
ํ๊ฒ ์ต๋๋ค.
๊ทธ๋ฌ๋ฉด
Body = {"id":100,"item":"book","user":"klom","deliveryTime":null,"deliveryEndTime":null,"itemPrice":null}
@JsonIgnore์ด ๋ถ์ด์๋ ๊ณณ์ json์ผ๋ก ๋ง๋ค์ด์ง์ง ์๋๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด json๋ ์ ์งํ๋ฉด์ ์๋ฌ๋ฅผ ์ฑ๊ณตํ๋ ๋ฐฉ๋ฒ์ ์์๊น์?
dto๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์
๋๋ค.
dto๋ api๋ฅผ ์ํด ๋ง๋ค์ด์ง๋ ๊ฐ์ฒด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ ๊ฒ ๊ฐ์ต๋๋ค.
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class DeliveryDto {
private String item;
private String user;
private LocalDateTime deliveryTime;
private LocalDateTime deliveryEndTime;
private Integer itemPrice;
}
์ด๋ ๊ฒ ๋ง๋ค๊ตฌ,
์ด์ ์
๋ ฅ์ deliveyDto๋ก ๋ฐ๊ฒ ํ๊ฒ ์ต๋๋ค.
๊ทผ๋ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
dto๋ก ๋ฐ๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.
์ด๋ด๋๋ ์ด๋ป๊ฒ ํด์ผ๋ ๊น์?
์ฌ๊ธฐ์๋ ๋ช ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์กด์ฌํฉ๋๋ค.
์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ builder์ ์ด์ฉํด์ ๊ฐ์ ๋ฐ์ธ๋ฉํ๋ค.
Delivery deliver = Delivery.builder()
.item(deliveryDto.getItem())
.user(deliveryDto.getUser())
.build();
์ด๋ ๊ฒ ๊ฐ์ DeliveryDto์์ delivery๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.
๋ฌผ๋ก ํ
์คํธ๋ ์คํจ์
๋๋ค. ์ถํ์ ์ค๋ช
ํ๊ฒ ์ต๋๋ค.
๋ ๋ฒ์งธ ๋ฐฉ๋ฒ์ Modelmapper์ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
Modelmapper๋ ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๋ฐ์ธ๋ฉํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค.
์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์คํ๋งioc์์ ๊ด๋ฆฌํด์ฃผ์ง ์๊ธฐ ๋๋ฌธ์ ์ง์ ๋น์ผ๋ก ๋ฑ๋กํด์ค์ผํฉ๋๋ค.
์๋๋ฉด ๊ทธ๋ฅ ์ฐ๋๊ฐ.
๊ทธ๋ฌ๋ฉด
Delivery deliver = modelMapper.map(deliveryDto, Delivery.class);
๋จ ํ์ค๋ก ์์ฑ์ ์ํฌ ์ ์์ต๋๋ค.
๋ฆฌํ๋ ์
๊ธฐ์ ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ข ๊ทธ๋ ๋ค ํ๋ ๋ถ๋ค์ ์ฌ์ฉํ์ง ์๋๊ฒ์ ์ถ์ฒ๋๋ฆฝ๋๋ค. ๊ทธ๋ฅ ๋น๋ ์ฐ์ธ์.
์๋ฐ ๋ฒ์ ์ด ์ฌ๋ผ๊ฐ๋ฉด์ ๋ฆฌํ๋ ์
๊ธฐ์ ๋ ๊ทธ๋ฆฌ ๋๋ฆฌ์ง๋ ์๋๋ค๊ณ ํฉ๋๋ค.
์ด์

์ด ์ค๋ฅ๋ฅผ ํด๊ฒฐํด๋ด ์๋ค.
ํ ์คํธ ์ฝ๋๋ฅผ ๋ค์ ๋ด ์๋ค.
๊ฐ์ฅ ํฐ ๋ฌธ์ ๋
Mockito.when(deliveryRepository.save(delivery)).thenReturn(delivery);
๋ฐ๋ก ์ด ๋
์์
๋๋ค.
์ด๊ฒ์ด ๋ฌธ์ ์ธ ์ด์ ๋
์ปจํธ๋กค๋ฌ์์๋ deliveryDto๋ฅผ ๋ฐ๊ณ ์์ต๋๋ค.
๊ทธ๊ฒ์ delivery๋ก ๋ฐ๊พธ๋ ์์
์ ๊ฐ์ก์ต๋๋ค.
๊ทผ๋ฐ ์๊ฐํด์ผ ๋ ๊ฒ์ด ์ด ๋ฐ๊พผ delivery์ ํ
์คํธ์ delivery๋ ๊ฐ์ ๊ฐ์ฒด์ผ๊น์?
์ ์ฝ๋๋ ํ
์คํธ์ delivery๋ฅผ ๋งํ๊ณ ์์ต๋๋ค.
์ฆ, ๊ฐ์ ์ฃผ์๊ฐ์ด ๋ค์ด๊ฐ์ผ ์ ์ฝ๋๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๋ค๋ ๋ป์
๋๋ค.
์ปจํธ๋กค๋ฌ์ delivery : restapiset.Delivery@3b
ํ
์คํธ์ delivery : restapiset.Delivery@9f
๊ทธ๋ฌ๋ฉด ์ด๋ป๊ฒ ํด์ผ ๋ ๊น์?
์ฌ๊ธฐ์๋ ์ฌ๋ฌ ๊ฐ์ง๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ๋ชจ๋ delivey๊ฐ์ฒด๋ฅผ saveํ๋ค๋ฉด delivery๋ฅผ ๋ฆฌํด์ํค๋ฉด ๋ฉ๋๋ค.
import static org.mockito.ArgumentMatchers.any;
Mockito.when(deliveryRepository.save(any(Delivery.class))).thenReturn(delivery);
์๊ฐํด๋ ๊ฒ์ด ๋ชจ๋ delivery๊ฐ์ฒด๋ฅผ ํ์ฉํ ๊น์
๋๋ค.
๊ณผ์ฐ ์ด๋ ๊ฒ ํด๋ ์ข์๊น?
๋ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ฌ๋ผ์ด์ฑ ํ
์คํธ์ ์์น๋ฅผ ์คํ๋ง๋ถํธ ํ
์คํธ๋ก ์์ ํ๋ ๊ฒ์
๋๋ค.
ํ์ง๋ง ๋ฌธ์ ๋ mockMvc๋ฅผ ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.
@SpringBootTest
@AutoConfigureMockMvc
class DeliveryTest {
์ด๊ฑธ ๋ถ์ด๋ ์๊ฐ mockMvc๋ฅผ ์ฌ์ฉํ ์์๊ฒ ๋ฉ๋๋ค.
์ด๋ ๊ฒ ๋๋ฉด ๋ ์ด์ ๋ชฉ๋น์ ํ์์์ต๋๋ค.
์๋ํ๋ฉด ํ
์คํธ์์ saveํ ์ด์ ๊ฐ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ง์ง๋ง์ผ๋ก delivery๋ฅผ ์์ ํฉ์๋ค.
public class Delivery {
@Id
@GeneratedValue
private int id;
private String item;
private String user;
private LocalDateTime deliveryTime;
private LocalDateTime deliveryEndTime;
private DeliveryStatus status = DeliveryStatus.READY;
private Integer itemPrice;
private Integer deliveryCost = 5000;
}
์ด๊ธฐ๊ฐ์ ์ด๋ ๊ฒ ์ธํ
ํด ๋๊ณ ,
spring.jackson.deserialization.fail-on-unknown-properties=true
ํ
์คํธ๋ฅผ ํ๊ฒ ๋๋ฉด ์๋ชป๋ ๊ฐ์ด ๋ค์ด์ค๋ฉด 400์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
'๊ฐ๋ฐ > restAPI๐ข' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| RestApi ๋ง๋ค๊ธฐ - spring-rest-docs (5) (0) | 2021.02.19 |
|---|---|
| RestApi ๋ง๋ค๊ธฐ - HATEOAS (5) (0) | 2021.02.16 |
| RestApi ๋ง๋ค๊ธฐ - badRequest (4) (0) | 2021.02.13 |
| RestApi ๋ง๋ค๊ธฐ - Repository์ถ๊ฐํ๊ธฐ (2) (0) | 2021.02.06 |
| RestApi ๋ง๋ค๊ธฐ - 201์ฝ๋ ์์ฑํ๊ธฐ (1) (0) | 2021.01.30 |