티스토리 뷰

TIL(Today I Learn)

TIL 220606

minji_6119 2022. 6. 6. 21:07

객체의 양방향 관계

객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개다.

객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야한다.

 

연관관계의 주인(Owner)

양방향 매핑 규칙

  • 객체의 두 관계중 하나를 연관관계의 주인으로 지정
  • 연관관계의 주인만이 외래키를 관리(등록, 수정)
  • 주인이 아닌 쪽은 읽기만 가능
  • 주인은 mappedBy 속성 사용하지 않음
  • 주인이 아니면 mappedBy 속성으로 주인 지정

누구를 주인으로?

외래 키가 있는 곳을 주인으로 정해라.

Entity의 관계를 모두 단방향으로 설정한 후 필요할 때만 양방향 관계를 설정한다.

 

심화과제 테스트 코드 분석

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class OrderIntegrationTest {
    @Autowired
    private TestRestTemplate restTemplate;

    private HttpHeaders headers;
    private ObjectMapper mapper = new ObjectMapper();

    private RestaurantDto registeredRestaurant;

    private FoodDto food1 = FoodDto.builder()
            .id(null)
            .name("쉑버거 더블")
            .price(10900)
            .build();

@TestInstance(TestInstance.Lifecycle.PER_CLASS): 테스트 코드의 라이프 사이클은 클래스 기준
@TestMethodOrder(MethodOrderer.OrderAnnotation.class): 테스트 코드의 순서 정하기

 

 

@Autowired
    private TestRestTemplate restTemplate

: HTTP 요청 후 데이터를 응답 받을 수 있는 템플릿 객체

    private HttpHeaders headers;

: HTTP의 헤더 부분 선언


    private ObjectMapper mapper = new ObjectMapper();

: 자바 객체를 JSON화 시키는 mapper

    private RestaurantDto registeredRestaurant;

: 음식점 등록 Test에서 음식점 등록 성공시 registeredRestaurant에 값 할당

@BeforeEach
public void setup() {
    headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
}

@BeforeEachHTTP헤더 부분 설정함으로써 테스트 코드에서 보내는 RequestBody의 ContentType은 JSON이라고 명시

@Test
@Order(1)
@DisplayName("음식점1 등록")
void test1() throws JsonProcessingException {
    // given
    RestaurantDto restaurantRequest = RestaurantDto.builder()
            .id(null)
            .name("쉐이크쉑 청담점")
            .minOrderPrice(5000)
            .deliveryFee(1000)
            .build();

    String requestBody = mapper.writeValueAsString(restaurantRequest);
    HttpEntity<String> request = new HttpEntity<>(requestBody, headers);

    // when
    ResponseEntity<RestaurantDto> response = restTemplate.postForEntity(
            "/restaurant/register",
            request,
            RestaurantDto.class);

    // then
    assertEquals(HttpStatus.OK, response.getStatusCode());

    RestaurantDto restaurantResponse = response.getBody();
    assertNotNull(restaurantResponse);
    assertTrue(restaurantResponse.id > 0);
    assertEquals(restaurantRequest.name, restaurantResponse.name);
    assertEquals(restaurantRequest.minOrderPrice, restaurantResponse.minOrderPrice);
    assertEquals(restaurantRequest.deliveryFee, restaurantResponse.deliveryFee);

    // 음식점 등록 성공 시, registeredRestaurant 에 할당
    registeredRestaurant = restaurantResponse;
}

*** void test1() throws JsonProcessingException

: 음식점을 등록하는 test1 메소드는 다른 테스트 class 내부에 있는 것이 아니라 통합 테스트(IntegtationTest)에서 선언된 메소드.  @TestInstance(TestInstance.Lifecycle.PER_CLASS)에서 선언한 바와 같이 테스트 코드의 라이프 사이클은 클래스 기준이다. 따라서 테스트마다

Long restaurantId = registeredRestaurant.id;

로 음식점의 Id를 받아오는 것이 가능해짐.

 

String requestBody = mapper.writeValueAsString(restaurantRequest);

: restaurantRequest를 JSON화 시켜 requestBody에 저장 (throws JsonProcessingException이 필요한 이유)


    HttpEntity<String> request = new HttpEntity<>(requestBody, headers);
: requestBody와 Header를 하나로 요청하기 위해서 HttpEntity로 묶는다. 
  
    ResponseEntity<RestaurantDto> response = restTemplate.postForEntity(
            "/restaurant/register",
            request,
            RestaurantDto.class);

: restTemplate.postForEntity(url, HttpEntity, response받을 class)

-> postForEntity: HttpEntity를 POST 요청으로 보낸다.

->  ResponseEntity<RestaurantDto> Response받을 class타입

 

assertEquals(HttpStatus.OK, response.getStatusCode());

RestaurantDto restaurantResponse = response.getBody();

assertEqual / assertNotNull / assertThrow

: 원하는 결과가 일치하는 지 확인하기 위함. (두 값이 같지 않으면 / 값이 null이 아니면 / exception이 나지 않으면 테스트 실패)

 

ResponseEntitiy.getBody를 함으로써 응답받은 RestaurantDto를 확인할 수 있다.

 

ResponseEntity<FoodDto[]> response = restTemplate.getForEntity(
        "/restaurant/" + restaurantId + "/foods",
        FoodDto[].class);
        
FoodDto food2Response = Arrays.stream(foodsResponse)
            .filter(food -> food2.getName().equals(food.getName()))
            .findAny()
            .orElse(null);
    assertNotNull(food2Response);
    assertNotNull(food2Response.getId());
    assertEquals(food2.getName(), food2Response.getName());
    assertEquals(food2.getPrice(), food2Response.getPrice());

음식점의 음식 정보 List를 받고, response받은 음식 정보 List중에서 food2와 같은 이름의 FoodDto가 존재하는지 확인한다.

'TIL(Today I Learn)' 카테고리의 다른 글

WIL 5주차(Week I Learn)  (0) 2022.06.19
TIL 220609  (0) 2022.06.09
TIL 220603  (0) 2022.06.03
TIL 220603  (0) 2022.06.03
TIL 220602  (0) 2022.06.02
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함