diff --git a/build.gradle.kts b/build.gradle.kts index 3aa9d0d2..0b77b3d1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -63,6 +63,7 @@ dependencies { testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.security:spring-security-test") testRuntimeOnly("org.junit.platform:junit-platform-launcher") + testImplementation("com.squareup.okhttp3:mockwebserver:3.14.9") //외부 api 서버 테스트용 // 스프링 문서화 implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.13") diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoTestController.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java similarity index 52% rename from src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoTestController.java rename to src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java index cc46af58..594d4639 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoTestController.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java @@ -18,65 +18,36 @@ @RestController @RequestMapping("/api/v1/location/kakao") @RequiredArgsConstructor -public class KakaoTestController { +public class KakaoApiController { private final KakaoLocalService kakaoLocalService; - @Operation( - summary = "주변 음식점 조회(테스트)", - description = "테스트용 하드코딩 좌표(서울 시청 근처)로 카카오 로컬에서 주변 음식점을 조회합니다., 하드코딩 좌표 : lat - 37.5665, lng -126.9780" - ) - @ApiResponse(responseCode = "200", description = "조회 성공", - content = @Content(schema = @Schema(implementation = KakaoLocalResponse.Document.class))) - @GetMapping("/restaurants") - - public List testKakaoRestaurants() { - - double lat = 37.5665; - double lng = 126.9780; - - return kakaoLocalService.searchNearbyRestaurants(lat, lng); - } @Operation( - summary = "주변 음식점 조회(테스트)", - description = "테스트용 좌표(서울 시청 근처)로 카카오 로컬에서 주변 음식점을 조회합니다, 좌표는 입력하면 됩니다." + - "예시 : http://localhost:8080/api/v1/location/kakao/restaurant?lat=37.5665&lng=126.9780" + summary = "주변 음식점 조회", + description = "좌표(서울 시청 근처)로 카카오 로컬에서 주변 음식점을 조회합니다, 좌표는 입력하면 됩니다." + + "예시 : http://localhost:8080/api/v1/location/kakao/restaurant?lat=37.5665&lon=126.9780" ) @PostMapping("/restaurant") public List KakaoRestaurants( @RequestParam double lat, - @RequestParam double lng + @RequestParam double lon ){ - return kakaoLocalService.searchNearbyRestaurants(lat, lng); + return kakaoLocalService.searchNearbyRestaurants(lat, lon); } - @Operation( - summary = "주변 카페 조회(테스트)", - description = "테스트용 하드코딩 좌표(서울 시청 근처)로 카카오 로컬에서 주변 카페를 조회합니다., 하드코딩 좌표 : lat - 37.5665, lng -126.9780" - ) - @ApiResponse(responseCode = "200", description = "조회 성공", - content = @Content(schema = @Schema(implementation = KakaoLocalResponse.Document.class))) - @GetMapping("/cafes") - public List testKakaoCafes() { - - double lat = 37.5665; - double lng = 126.9780; - - return kakaoLocalService.searchNearbyCafes(lat, lng); - } @Operation( - summary = "주변 카페 조회(테스트)", - description = "테스트용 좌표(서울 시청 근처)로 카카오 로컬에서 주변 카페를 조회합니다, 좌표는 입력하면 됩니다." + - "예시 : http://localhost:8080/api/v1/location/kakao/cafes?lat=37.5665&lng=126.9780" + summary = "주변 카페 조회", + description = "좌표(서울 시청 근처)로 카카오 로컬에서 주변 카페를 조회합니다, 좌표는 입력하면 됩니다." + + "예시 : http://localhost:8080/api/v1/location/kakao/cafes?lat=37.5665&lon=126.9780" ) @PostMapping("/cafes") public List KakaoCafes( @RequestParam double lat, - @RequestParam double lng + @RequestParam double lon ){ - return kakaoLocalService.searchNearbyCafes(lat, lng); + return kakaoLocalService.searchNearbyCafes(lat, lon); } diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapController.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java similarity index 98% rename from src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapController.java rename to src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java index 6119270f..fb45f64a 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapController.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java @@ -17,7 +17,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("/api/v1/location") -public class TmapController { +public class TmapApiController { private final TmapService tmapService; diff --git a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java index dcf7200a..01ad8736 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java +++ b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java @@ -30,6 +30,11 @@ public class WebClientConfig { @Value("${kakao.restapi-key}") private String kakaomapApiKey; + @Value("${kakao.base-url}") + private String kakaoBaseUrl; + + @Value("${tmap.base-url}") + private String tmapBaseUrl; @Bean public WebClient mailgunClient() { String auth = "api:" + mailgunApiKey; @@ -58,8 +63,9 @@ public RestTemplate restTemplate() { @Bean public WebClient kakaoWebClient() { + return WebClient.builder() - .baseUrl("https://dapi.kakao.com") + .baseUrl(kakaoBaseUrl) .defaultHeader("Authorization", kakaomapApiKey) .build(); } @@ -68,7 +74,7 @@ public WebClient kakaoWebClient() { @Bean public WebClient TmapClient(){ return WebClient.builder() - .baseUrl("https://apis.openapi.sk.com") + .baseUrl(tmapBaseUrl) .defaultHeader("appKey", tmapApiKey) .build(); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 74a888c1..0f894175 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -39,10 +39,13 @@ jwt: refresh-token-expiration: 1209600 # 14일 tmap: #Tmap 대중교통 추천 api 키 + base-url: https://apis.openapi.sk.com api-key: ${TMAP_API_KEY} kakao: #Kakao map REST API 키 + base-url: https://dapi.kakao.com restapi-key: ${KAKAOMAP_API_KEY} + kopis: api-key: ${KOPIST_API_KEY} spotify: diff --git a/src/test/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiControllerTest.java b/src/test/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiControllerTest.java new file mode 100644 index 00000000..64b7609b --- /dev/null +++ b/src/test/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiControllerTest.java @@ -0,0 +1,175 @@ +//package com.back.web7_9_codecrete_be.domain.location.controller; +// +//import okhttp3.mockwebserver.MockResponse; +//import okhttp3.mockwebserver.MockWebServer; +//import org.junit.jupiter.api.*; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +//import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +//import org.springframework.context.annotation.Import; +//import org.springframework.test.context.ActiveProfiles; +//import org.springframework.test.context.DynamicPropertyRegistry; +//import org.springframework.test.context.DynamicPropertySource; +//import org.springframework.test.web.servlet.MockMvc; +// +//import com.back.web7_9_codecrete_be.domain.location.service.KakaoLocalService; +//import com.back.web7_9_codecrete_be.global.config.WebClientConfig; // 네 프로젝트 패키지에 맞게 import 수정 +// +//import java.io.IOException; +//import java.net.URLEncoder; +//import java.nio.charset.StandardCharsets; +// +//import static org.assertj.core.api.Assertions.assertThat; +//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +//@AutoConfigureMockMvc(addFilters = false) +//@ActiveProfiles("test")@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +//@WebMvcTest(controllers = KakaoApiController.class) +//@Import({KakaoLocalService.class, WebClientConfig.class}) +//@TestInstance(TestInstance.Lifecycle.PER_CLASS) +//class KakaoApiControllerTest { +// +// private static MockWebServer server; +// +// @Autowired +// private MockMvc mockMvc; +// +// +// @AfterAll +// static void stopServer() throws IOException { +// if (server != null) server.shutdown(); +// } +// +// @DynamicPropertySource +// static void overrideProps(DynamicPropertyRegistry r) { +// try { +// if (server == null) { +// server = new MockWebServer(); +// server.start(); +// } +// } catch (IOException e) { +// throw new RuntimeException(e); +// } +// +// r.add("kakao.base-url", () -> server.url("/").toString()); +// r.add("kakao.restapi-key", () -> "KakaoAK test-key"); +// } +// +// @Test +// void POST_restaurant_우리API호출하면_카카오연동을거쳐_응답이온다() throws Exception { +// server.enqueue(new MockResponse() +// .setResponseCode(200) +// .addHeader("Content-Type", "application/json; charset=UTF-8") +// .setBody(""" +// { +// "documents": [ +// { +// "place_name": "테스트식당", +// "x": "127.0", +// "y": "37.5", +// "road_address_name": "서울 ...", +// "address_name": "서울 ...", +// "place_url": "https://place.map.kakao.com/111" +// } +// ] +// } +// """)); +// +// mockMvc.perform(post("/api/v1/location/kakao/restaurant") +// .param("lat", "37.5") +// .param("lon", "127.0")) +// .andExpect(status().isOk()) +// .andExpect(jsonPath("$[0].place_name").value("테스트식당")) +// .andExpect(jsonPath("$[0].x").value("127.0")) +// .andExpect(jsonPath("$[0].y").value("37.5")); +// +// var req = server.takeRequest(); +// assertThat(req.getMethod()).isEqualTo("GET"); +// assertThat(req.getHeader("Authorization")).isEqualTo("KakaoAK test-key"); +// +// assertThat(req.getPath()).startsWith("/v2/local/search/keyword.json?"); +// String encoded = URLEncoder.encode("음식점", StandardCharsets.UTF_8); +// assertThat(req.getPath()).contains("query=" + encoded); +// assertThat(req.getPath()).contains("y=37.5"); +// assertThat(req.getPath()).contains("x=127.0"); +// assertThat(req.getPath()).contains("radius=1000"); +// assertThat(req.getPath()).contains("sort=distance"); +// } +// +// @Test +// void POST_cafes_우리API호출하면_카카오연동을거쳐_응답이온다() throws Exception { +// server.enqueue(new MockResponse() +// .setResponseCode(200) +// .addHeader("Content-Type", "application/json; charset=UTF-8") +// .setBody(""" +// { +// "documents": [ +// { +// "place_name": "테스트카페", +// "x": "126.9780", +// "y": "37.5665", +// "road_address_name": "서울 ...", +// "address_name": "서울 ...", +// "place_url": "https://place.map.kakao.com/222" +// } +// ] +// } +// """)); +// +// mockMvc.perform(post("/api/v1/location/kakao/cafes") +// .param("lat", "37.5665") +// .param("lon", "126.9780")) +// .andExpect(status().isOk()) +// .andExpect(jsonPath("$[0].place_name").value("테스트카페")) +// .andExpect(jsonPath("$[0].x").value("126.9780")) +// .andExpect(jsonPath("$[0].y").value("37.5665")); +// +// var req = server.takeRequest(); +// assertThat(req.getMethod()).isEqualTo("GET"); +// assertThat(req.getHeader("Authorization")).isEqualTo("KakaoAK test-key"); +// +// assertThat(req.getPath()).startsWith("/v2/local/search/keyword.json?"); +// String encoded = URLEncoder.encode("카페", StandardCharsets.UTF_8); +// assertThat(req.getPath()).contains("query=" + encoded); +// assertThat(req.getPath()).contains("category_group_code=CE7"); +// assertThat(req.getPath()).contains("y=37.5665"); +// assertThat(req.getPath()).contains("x=126.9780"); +// assertThat(req.getPath()).contains("radius=1000"); +// assertThat(req.getPath()).contains("sort=distance"); +// } +// +// @Test +// void GET_coord2address_우리API호출하면_RsData로주소가온다() throws Exception { +// server.enqueue(new MockResponse() +// .setResponseCode(200) +// .addHeader("Content-Type", "application/json; charset=UTF-8") +// .setBody(""" +// { +// "documents": [ +// { +// "road_address": { "address_name": "서울특별시 중구 세종대로 110" }, +// "address": { "address_name": "서울특별시 중구 태평로1가 31" } +// } +// ] +// } +// """)); +// +// mockMvc.perform(get("/api/v1/location/kakao/coord2address") +// .param("lat", "37.5665") +// .param("lon", "126.9780")) +// .andExpect(status().isOk()) +// .andExpect(jsonPath("$.status").value(200)) +// .andExpect(jsonPath("$.resultCode").value("OK")) +// .andExpect(jsonPath("$.msg").value("좌표를 주소로 변환했습니다.")) +// .andExpect(jsonPath("$.data").value("서울특별시 중구 세종대로 110")); +// +// var req = server.takeRequest(); +// assertThat(req.getMethod()).isEqualTo("GET"); +// assertThat(req.getHeader("Authorization")).isEqualTo("KakaoAK test-key"); +// +// assertThat(req.getPath()).startsWith("/v2/local/geo/coord2address.json?"); +// assertThat(req.getPath()).contains("x=126.978"); +// assertThat(req.getPath()).contains("y=37.5665"); +// } +//} diff --git a/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalServiceTest.java b/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalServiceTest.java new file mode 100644 index 00000000..a44046f1 --- /dev/null +++ b/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalServiceTest.java @@ -0,0 +1,178 @@ +package com.back.web7_9_codecrete_be.domain.location.service; + +import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse; +import com.back.web7_9_codecrete_be.global.config.WebClientConfig; +import com.back.web7_9_codecrete_be.global.error.exception.BusinessException; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; + +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static org.assertj.core.api.Assertions.*; + +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.NONE, + classes = { KakaoLocalService.class, WebClientConfig.class } +) //다른 api들 까지 검사 말고, 카카오 api만 검사하려고 이렇게 설정 +@Import(WebClientConfig.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) //테스트마다 인스턴스를 새로 만들지 말고, 1개만 사용하게 하기 +class KakaoLocalServiceTest { + + private static MockWebServer server; //가짜 카카오 서버를 테스트에서 공유함 + + @Autowired + private KakaoLocalService kakaoLocalService; //내가 검사하고싶은 서비스 + + @DynamicPropertySource //스프링 컨텍스트가 만들어지기 전에 property를 동적으로 주입하는 훅 + //스프링에게 ‘이 설정값은 이렇게 써라’라고 알려주는 등록기 + static void overrideProps(DynamicPropertyRegistry r) { + try { + if (server == null) { + server = new MockWebServer(); + server.start(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + // 카카오 API 주소와 키를 Mock서버, 테스트 키로 바꾸기 + r.add("kakao.base-url", () -> server.url("/").toString()); // MockWebServer는 랜덤 포트라서 동적으로 넣어줘야 함 + r.add("kakao.restapi-key", () -> "KakaoAK test-key"); + } + + //순서 : DynamicPropertySource -> Spring Context -> WebClient Bean 생성 + + + @AfterAll + static void shutdown() throws IOException { + if (server != null) server.shutdown(); + } + + @BeforeEach + void resetQueueByDesign() { + // 이 테스트는 서버 재시작으로 큐를 리셋하지 않고, + // 테스트 구조로 큐 격리를 보장 + } + + @Test + void searchNearbyRestaurantsTest() throws Exception { + server.enqueue(new MockResponse() // setBody에 있는 요청에 대한 응답을 enqueue에 넣기 + .setResponseCode(200) + .addHeader("Content-Type", "application/json; charset=UTF-8") + .setBody(""" + { + "documents": [ + { "place_name": "테스트식당", "x": "127.0", "y": "37.5" } + ] + } + """)); //setBody : 실제 JSON 응답 body + + //kakasLocalService에 있는 searchNearByRestaurants 함수에 위도, 경도를 넣고 WebClient가 호출해서 응답을 반환 + List docs = + kakaoLocalService.searchNearbyRestaurants(37.5, 127.0); + + assertThat(docs).hasSize(1); //응답 배열의 크기가 1인지 + assertThat(docs.get(0).getPlace_name()).isEqualTo("테스트식당"); // 제대로 필드가 들어갔는지 확인 + + //여기서부터는 MockWebServer가 실제로 받은 요청을 검사 + var req = server.takeRequest(); + assertThat(req.getMethod()).isEqualTo("GET"); //컨트롤러가 POST지만, 이거는 WebClient에서 GET을 하는거라서 GET이 맞음, 즉 내 서버 -> 카카오 서버 요청이라서 + assertThat(req.getHeader("Authorization")).isEqualTo("KakaoAK test-key"); //인증 헤더가 잘 들어갔는지 확인 + + assertThat(req.getPath()).startsWith("/v2/local/search/keyword.json?"); + String encoded = URLEncoder.encode("음식점", StandardCharsets.UTF_8); + assertThat(req.getPath()).contains("query=" + encoded); + assertThat(req.getPath()).contains("y=37.5"); + assertThat(req.getPath()).contains("x=127.0"); + assertThat(req.getPath()).contains("radius=1000"); + assertThat(req.getPath()).contains("sort=distance"); + } + +// 이제부터 밑에있는 테스트는 위에 있는 테스트와 비슷하므로 따로 추가 설명은 안썼습니다 + + @Test + void searchNearbyCafesTest() throws Exception { + server.enqueue(new MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json; charset=UTF-8") + .setBody(""" + { + "documents": [ + { "place_name": "테스트카페", "x": "126.978", "y": "37.5665" } + ] + } + """)); + + List docs = + kakaoLocalService.searchNearbyCafes(37.5665, 126.9780); + + assertThat(docs).hasSize(1); + assertThat(docs.get(0).getPlace_name()).isEqualTo("테스트카페"); + + var req = server.takeRequest(); + assertThat(req.getMethod()).isEqualTo("GET"); + assertThat(req.getHeader("Authorization")).isEqualTo("KakaoAK test-key"); + + assertThat(req.getPath()).startsWith("/v2/local/search/keyword.json?"); + String encoded = URLEncoder.encode("카페", StandardCharsets.UTF_8); + assertThat(req.getPath()).contains("query=" + encoded); + assertThat(req.getPath()).contains("category_group_code=CE7"); + assertThat(req.getPath()).contains("y=37.5665"); + assertThat(req.getPath()).contains("x=126.978"); + assertThat(req.getPath()).contains("radius=1000"); + assertThat(req.getPath()).contains("sort=distance"); + } + + @Test + void coordinateToAddressNameTest() throws Exception { + server.enqueue(new MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json; charset=UTF-8") + .setBody(""" + { + "documents": [ + { + "road_address": { "address_name": "서울특별시 중구 세종대로 110" }, + "address": { "address_name": "서울특별시 중구 태평로1가 31" } + } + ] + } + """)); + + String address = kakaoLocalService.coordinateToAddressName(37.5665, 126.9780); + + assertThat(address).isEqualTo("서울특별시 중구 세종대로 110"); + + var req = server.takeRequest(); + assertThat(req.getMethod()).isEqualTo("GET"); + assertThat(req.getHeader("Authorization")).isEqualTo("KakaoAK test-key"); + + assertThat(req.getPath()).startsWith("/v2/local/geo/coord2address.json?"); + assertThat(req.getPath()).contains("x=126.978"); + assertThat(req.getPath()).contains("y=37.5665"); + } + + @Test + void coordinateToAddressName_documents가비면_BusinessException() throws Exception { + server.enqueue(new MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json; charset=UTF-8") + .setBody("{\"documents\":[{\"place_name\":\"테스트카페\",\"x\":\"126.9780\",\"y\":\"37.5665\"}]}")); + + assertThatThrownBy(() -> kakaoLocalService.coordinateToAddressName(37.0, 127.0)) + .isInstanceOf(BusinessException.class); + + var req = server.takeRequest(); + assertThat(req.getMethod()).isEqualTo("GET"); + assertThat(req.getPath()).startsWith("/v2/local/geo/coord2address.json?"); + } +} diff --git a/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/TmapServiceTest.java b/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/TmapServiceTest.java new file mode 100644 index 00000000..d00223f4 --- /dev/null +++ b/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/TmapServiceTest.java @@ -0,0 +1,89 @@ +package com.back.web7_9_codecrete_be.domain.location.service; + +import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse; +import com.back.web7_9_codecrete_be.global.config.WebClientConfig; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + TmapService.class, + WebClientConfig.class +}) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class TmapServiceTest { + + private static MockWebServer server; //가짜 tmap 서버를 테스트에서 공유함 + + @Autowired + private TmapService tmapService; + + @DynamicPropertySource + static void overrideProps(DynamicPropertyRegistry r) { + try { + if (server == null) { + server = new MockWebServer(); + server.start(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + // tmap API 주소와 키를 Mock서버, 테스트 키로 바꾸기 + r.add("tmap.base-url", () -> server.url("/").toString()); // MockWebServer는 랜덤 포트라서 동적으로 넣어줘야 함 + r.add("tmap.restapi-key", () -> "test-key"); + } + @AfterAll + static void shutdown() throws IOException { + if (server != null) server.shutdown(); + } + @Test + void getRoute() throws Exception { + server.enqueue(new MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json; charset=UTF-8") + .setBody(""" + { + "metaData": { + "plan": { + "itineraries": [ + { + "totalTime": 600, + "totalFare": { "regular": 1250 } + } + ] + } + } + } + """)); + + String result = tmapService.getRoute( + 126.977969, 37.566535, + 126.986037, 37.563617 + ); + + assertThat(result).contains("totalTime"); + assertThat(result).contains("1250"); + + var req = server.takeRequest(); + assertThat(req.getMethod()).isEqualTo("POST"); + } +}