From d0a39f6befe72574eacb657a8ae1644dc47f9729 Mon Sep 17 00:00:00 2001 From: dd Date: Fri, 15 May 2020 11:23:12 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20PathServiceTest=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 해피케이스에 대한 테스트 구현 - 예외사항에 대한 테스트 구현 --- .../subway/admin/config/ETagHeaderFilter.java | 1 - .../admin/controller/PathController.java | 4 +- .../subway/admin/dto/PathRequestWithId.java | 25 --- .../IllegalStationNameException.java | 5 +- .../exception/NotFoundLineException.java | 4 + .../exception/NotFoundStationException.java | 4 + .../subway/admin/service/GraphService.java | 26 ++- .../subway/admin/service/PathService.java | 28 +-- .../subway/admin/service/StationService.java | 5 - .../admin/acceptance/PathAcceptanceTest.java | 1 - .../subway/admin/service/PathServiceTest.java | 171 ++++++++++++++++++ 11 files changed, 208 insertions(+), 66 deletions(-) delete mode 100644 src/main/java/wooteco/subway/admin/dto/PathRequestWithId.java create mode 100644 src/test/java/wooteco/subway/admin/service/PathServiceTest.java diff --git a/src/main/java/wooteco/subway/admin/config/ETagHeaderFilter.java b/src/main/java/wooteco/subway/admin/config/ETagHeaderFilter.java index 943ff5410..89bd7a193 100644 --- a/src/main/java/wooteco/subway/admin/config/ETagHeaderFilter.java +++ b/src/main/java/wooteco/subway/admin/config/ETagHeaderFilter.java @@ -17,5 +17,4 @@ public class ETagHeaderFilter { filter.setName("etagFilter"); return filter; } - } diff --git a/src/main/java/wooteco/subway/admin/controller/PathController.java b/src/main/java/wooteco/subway/admin/controller/PathController.java index 79b5509c7..ade14478f 100644 --- a/src/main/java/wooteco/subway/admin/controller/PathController.java +++ b/src/main/java/wooteco/subway/admin/controller/PathController.java @@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.RestController; import wooteco.subway.admin.dto.PathRequest; -import wooteco.subway.admin.dto.PathRequestWithId; import wooteco.subway.admin.dto.PathResponse; import wooteco.subway.admin.service.PathService; @@ -25,8 +24,7 @@ public PathController(PathService pathService) { @PostMapping ResponseEntity findPath(@Valid @RequestBody PathRequest pathRequest) { - PathRequestWithId PathRequestWithId = pathService.toPathRequestWithId(pathRequest); - PathResponse response = pathService.findPath(PathRequestWithId); + PathResponse response = pathService.findPath(pathRequest); return ResponseEntity.ok(response); } diff --git a/src/main/java/wooteco/subway/admin/dto/PathRequestWithId.java b/src/main/java/wooteco/subway/admin/dto/PathRequestWithId.java deleted file mode 100644 index a90d1f7fe..000000000 --- a/src/main/java/wooteco/subway/admin/dto/PathRequestWithId.java +++ /dev/null @@ -1,25 +0,0 @@ -package wooteco.subway.admin.dto; - -public class PathRequestWithId { - private final Long sourceId; - private final Long targetId; - private final PathType pathType; - - public PathRequestWithId(Long sourceId, Long targetId, PathType pathType) { - this.sourceId = sourceId; - this.targetId = targetId; - this.pathType = pathType; - } - - public Long getSourceId() { - return sourceId; - } - - public Long getTargetId() { - return targetId; - } - - public PathType getPathType() { - return pathType; - } -} diff --git a/src/main/java/wooteco/subway/admin/exception/IllegalStationNameException.java b/src/main/java/wooteco/subway/admin/exception/IllegalStationNameException.java index db3548ad0..870651ff5 100644 --- a/src/main/java/wooteco/subway/admin/exception/IllegalStationNameException.java +++ b/src/main/java/wooteco/subway/admin/exception/IllegalStationNameException.java @@ -1,7 +1,8 @@ package wooteco.subway.admin.exception; public class IllegalStationNameException extends BusinessException { - public IllegalStationNameException(String sourceName) { - super(sourceName + " 이름이 중복되었습니다."); + + public IllegalStationNameException(Long sourceId, Long targetId) { + super(sourceId + ", " + targetId + " 역이 중복되었습니다."); } } diff --git a/src/main/java/wooteco/subway/admin/exception/NotFoundLineException.java b/src/main/java/wooteco/subway/admin/exception/NotFoundLineException.java index c11c34aae..52baf3c60 100644 --- a/src/main/java/wooteco/subway/admin/exception/NotFoundLineException.java +++ b/src/main/java/wooteco/subway/admin/exception/NotFoundLineException.java @@ -4,6 +4,10 @@ public class NotFoundLineException extends DataAccessException { + public NotFoundLineException() { + super("line을 찾을 수 없습니다"); + } + public NotFoundLineException(Long id) { super(id + "에 해당하는 line을 찾을 수 없습니다"); } diff --git a/src/main/java/wooteco/subway/admin/exception/NotFoundStationException.java b/src/main/java/wooteco/subway/admin/exception/NotFoundStationException.java index 46006c0b1..772107022 100644 --- a/src/main/java/wooteco/subway/admin/exception/NotFoundStationException.java +++ b/src/main/java/wooteco/subway/admin/exception/NotFoundStationException.java @@ -4,6 +4,10 @@ public class NotFoundStationException extends DataAccessException { + public NotFoundStationException() { + super("해당역을 찾을 수 없습니다"); + } + public NotFoundStationException(String name) { super(name + "역을 찾을 수 없습니다."); } diff --git a/src/main/java/wooteco/subway/admin/service/GraphService.java b/src/main/java/wooteco/subway/admin/service/GraphService.java index 4330bac68..ac9a99307 100644 --- a/src/main/java/wooteco/subway/admin/service/GraphService.java +++ b/src/main/java/wooteco/subway/admin/service/GraphService.java @@ -9,26 +9,34 @@ import wooteco.subway.admin.domain.Line; import wooteco.subway.admin.dto.GraphResponse; -import wooteco.subway.admin.dto.PathRequestWithId; import wooteco.subway.admin.dto.PathType; +import wooteco.subway.admin.exception.IllegalStationNameException; +import wooteco.subway.admin.exception.NotFoundLineException; import wooteco.subway.admin.exception.NotFoundPathException; @Service public class GraphService { - public GraphResponse findPath(List lines, PathRequestWithId request) { - Long source = request.getSourceId(); - Long target = request.getTargetId(); - PathType pathType = request.getPathType(); - + public GraphResponse findPath(List lines, Long sourceId, Long targetId, + PathType pathType) { + validate(lines, sourceId, targetId); WeightedMultigraph graph = mapLinesToGraph(lines, pathType); DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath<>( graph); - if (Objects.isNull(dijkstraShortestPath.getPath(source, target))) { - throw new NotFoundPathException(source, target); + if (Objects.isNull(dijkstraShortestPath.getPath(sourceId, targetId))) { + throw new NotFoundPathException(sourceId, targetId); } - return mapToGraphResponse(source, target, dijkstraShortestPath); + return mapToGraphResponse(sourceId, targetId, dijkstraShortestPath); + } + + private void validate(List lines, Long sourceId, Long targetId) { + if (Objects.isNull(lines)) { + throw new NotFoundLineException(); + } + if (Objects.equals(sourceId, targetId)) { + throw new IllegalStationNameException(sourceId, targetId); + } } private WeightedMultigraph mapLinesToGraph(List lines, diff --git a/src/main/java/wooteco/subway/admin/service/PathService.java b/src/main/java/wooteco/subway/admin/service/PathService.java index 81c393064..d7efc51e0 100644 --- a/src/main/java/wooteco/subway/admin/service/PathService.java +++ b/src/main/java/wooteco/subway/admin/service/PathService.java @@ -9,11 +9,10 @@ import wooteco.subway.admin.domain.Line; import wooteco.subway.admin.dto.GraphResponse; import wooteco.subway.admin.dto.PathRequest; -import wooteco.subway.admin.dto.PathRequestWithId; import wooteco.subway.admin.dto.PathResponse; import wooteco.subway.admin.dto.PathType; import wooteco.subway.admin.dto.StationResponse; -import wooteco.subway.admin.exception.IllegalStationNameException; +import wooteco.subway.admin.exception.NotFoundStationException; @Service @Transactional(readOnly = true) @@ -30,24 +29,13 @@ public PathService(StationService stationService, this.graphService = graphService; } - public PathRequestWithId toPathRequestWithId(PathRequest pathRequest) { - String sourceName = pathRequest.getSourceName(); - String targetName = pathRequest.getTargetName(); - PathType pathType = PathType.of(pathRequest.getType()); - - if (sourceName.equals(targetName)) { - throw new IllegalStationNameException(sourceName); - } - - Long sourceId = stationService.findIdByName(sourceName); - Long targetId = stationService.findIdByName(targetName); - - return new PathRequestWithId(sourceId, targetId, pathType); - } - - public PathResponse findPath(PathRequestWithId pathRequestWithId) { + public PathResponse findPath(PathRequest request) { + Long sourceId = stationService.findIdByName(request.getSourceName()); + Long targetId = stationService.findIdByName(request.getTargetName()); List lines = lineService.findAll(); - GraphResponse graphResponse = graphService.findPath(lines, pathRequestWithId); + + GraphResponse graphResponse = graphService.findPath(lines, sourceId, targetId, + PathType.of(request.getType())); List path = graphResponse.getPath(); List stationResponses = StationResponse.listOf( @@ -66,7 +54,7 @@ private List sort(List path, List statio for (Long stationId : path) { StationResponse response = stationResponses.stream() .filter(stationResponse -> stationResponse.getId().equals(stationId)) - .findAny().orElseThrow(IllegalArgumentException::new); + .findAny().orElseThrow(NotFoundStationException::new); result.add(response); } return result; diff --git a/src/main/java/wooteco/subway/admin/service/StationService.java b/src/main/java/wooteco/subway/admin/service/StationService.java index 09c529336..79f493062 100644 --- a/src/main/java/wooteco/subway/admin/service/StationService.java +++ b/src/main/java/wooteco/subway/admin/service/StationService.java @@ -6,13 +6,8 @@ import org.springframework.transaction.annotation.Transactional; import wooteco.subway.admin.domain.Station; -import wooteco.subway.admin.dto.PathRequest; -import wooteco.subway.admin.dto.PathRequestWithId; -import wooteco.subway.admin.dto.PathType; import wooteco.subway.admin.dto.StationCreateRequest; import wooteco.subway.admin.dto.StationResponse; -import wooteco.subway.admin.exception.IllegalStationNameException; -import wooteco.subway.admin.exception.NotFoundPathException; import wooteco.subway.admin.exception.NotFoundStationException; import wooteco.subway.admin.repository.StationRepository; diff --git a/src/test/java/wooteco/subway/admin/acceptance/PathAcceptanceTest.java b/src/test/java/wooteco/subway/admin/acceptance/PathAcceptanceTest.java index eb88b6b49..819ee7d6f 100644 --- a/src/test/java/wooteco/subway/admin/acceptance/PathAcceptanceTest.java +++ b/src/test/java/wooteco/subway/admin/acceptance/PathAcceptanceTest.java @@ -9,7 +9,6 @@ import wooteco.subway.admin.dto.LineResponse; import wooteco.subway.admin.dto.PathResponse; import wooteco.subway.admin.dto.StationResponse; -import wooteco.subway.admin.exception.IllegalTypeNameException; public class PathAcceptanceTest extends AcceptanceTest { diff --git a/src/test/java/wooteco/subway/admin/service/PathServiceTest.java b/src/test/java/wooteco/subway/admin/service/PathServiceTest.java new file mode 100644 index 000000000..f287f52ab --- /dev/null +++ b/src/test/java/wooteco/subway/admin/service/PathServiceTest.java @@ -0,0 +1,171 @@ +package wooteco.subway.admin.service; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.LocalTime; +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import wooteco.subway.admin.domain.Line; +import wooteco.subway.admin.domain.LineStation; +import wooteco.subway.admin.domain.Station; +import wooteco.subway.admin.dto.PathRequest; +import wooteco.subway.admin.dto.PathResponse; +import wooteco.subway.admin.dto.PathType; +import wooteco.subway.admin.dto.StationResponse; +import wooteco.subway.admin.exception.IllegalStationNameException; +import wooteco.subway.admin.exception.NotFoundLineException; +import wooteco.subway.admin.exception.NotFoundPathException; +import wooteco.subway.admin.exception.NotFoundStationException; + +@ExtendWith(MockitoExtension.class) +class PathServiceTest { + private static final String STATION_NAME1 = "잠실역"; + private static final String STATION_NAME2 = "잠실새내역"; + private static final String STATION_NAME3 = "종합운동장역"; + private static final String STATION_NAME4 = "삼전역"; + private static final String STATION_NAME5 = "석촌고분역"; + private static final String STATION_NAME6 = "석촌역"; + private static final String STATION_NAME7 = "부산역"; + private static final String STATION_NAME8 = "대구역"; + private static final String STATION_NAME9 = "런던역"; + + @Mock + private StationService stationService; + + @Mock + private LineService lineService; + + private GraphService graphService; + + private PathService pathService; + + private Line line1; + private Line line2; + private Line line3; + private Line line4; + private Station station1; + private Station station2; + private Station station3; + private Station station4; + private Station station5; + private Station station6; + private Station station7; + private Station station8; + private Station station9; + + private List lines; + private List stations; + + @BeforeEach + void setUp() { + graphService = new GraphService(); + pathService = new PathService(stationService, lineService, graphService); + + station1 = new Station(1L, STATION_NAME1); + station2 = new Station(2L, STATION_NAME2); + station3 = new Station(3L, STATION_NAME3); + station4 = new Station(4L, STATION_NAME4); + station5 = new Station(5L, STATION_NAME5); + station6 = new Station(6L, STATION_NAME6); + station7 = new Station(7L, STATION_NAME7); + station8 = new Station(8L, STATION_NAME8); + station9 = new Station(9L, STATION_NAME8); + + line1 = new Line(1L, "2호선", "bg-green-400", LocalTime.of(05, 30), LocalTime.of(22, 30), 5); + line1.addLineStation(new LineStation(null, 1L, 0, 0)); + line1.addLineStation(new LineStation(1L, 2L, 10, 1)); + line1.addLineStation(new LineStation(2L, 3L, 10, 1)); + line1.addLineStation(new LineStation(3L, 4L, 10, 1)); + + line2 = new Line(2L, "8호선", "bg-pink-600", LocalTime.of(05, 30), LocalTime.of(22, 30), 5); + line2.addLineStation(new LineStation(null, 1L, 1, 10)); + line2.addLineStation(new LineStation(1L, 6L, 1, 10)); + + line3 = new Line(3L, "9호선", "bg-yellow-700", LocalTime.of(05, 30), LocalTime.of(22, 30), 5); + line3.addLineStation(new LineStation(null, 3L, 0, 0)); + line3.addLineStation(new LineStation(3L, 4L, 1, 10)); + line3.addLineStation(new LineStation(4L, 5L, 1, 10)); + line3.addLineStation(new LineStation(5L, 6L, 1, 10)); + + line4 = new Line(4L, "대구1호선", "bg-indigo-500", LocalTime.of(05, 30), LocalTime.of(22, 30), + 5); + line4.addLineStation(new LineStation(null, 7L, 0, 0)); + line4.addLineStation(new LineStation(7L, 8L, 20, 20)); + + stations = Arrays.asList(station1, station2, station3, station4, station5, station6, + station7, station8); + lines = Arrays.asList(line1, line2, line3, line4); + } + + @Test + void findPathForNextStation() { + PathRequest request = new PathRequest(station1.getName(), + station2.getName(), PathType.DISTANCE.name()); + + when(stationService.findIdByName(station1.getName())).thenReturn(station1.getId()); + when(stationService.findIdByName(station2.getName())).thenReturn(station2.getId()); + when(lineService.findAll()).thenReturn(lines); + when(stationService.findAllById(anyList())).thenReturn(Arrays.asList(station1, station2)); + PathResponse path = pathService.findPath(request); + + assertThat(path.getStations()).extracting(StationResponse::getName) + .containsExactly(station1.getName(), + station2.getName()); + assertThat(path.getTotalDistance()).isEqualTo(10); + assertThat(path.getTotalDuration()).isEqualTo(1); + } + + @Test + void findPathForNotConnectedStation() { + PathRequest request = new PathRequest(station1.getName(), + station8.getName(), PathType.DISTANCE.name()); + + when(stationService.findIdByName(station1.getName())).thenReturn(station1.getId()); + when(stationService.findIdByName(station8.getName())).thenReturn(station8.getId()); + when(lineService.findAll()).thenReturn(lines); + assertThatThrownBy(() -> pathService.findPath(request)) + .isInstanceOf(NotFoundPathException.class); + } + + @Test + void findPathForSameStation() { + PathRequest request = new PathRequest(station1.getName(), + station1.getName(), PathType.DISTANCE.name()); + + when(lineService.findAll()).thenReturn(lines); + when(stationService.findIdByName(anyString())).thenReturn(station1.getId()); + assertThatThrownBy(() -> pathService.findPath(request)) + .isInstanceOf(IllegalStationNameException.class); + } + + @Test + void findPathForNotExistStation() { + PathRequest request = new PathRequest(station1.getName(), station9.getName(), + PathType.DISTANCE.name()); + + when(stationService.findIdByName(station1.getName())).thenReturn(station1.getId()); + when(stationService.findIdByName(station9.getName())) + .thenThrow(new NotFoundStationException()); + assertThatThrownBy(() -> pathService.findPath(request)) + .isInstanceOf(NotFoundStationException.class); + } + + @Test + void findPathForNotExistLines() { + PathRequest request = new PathRequest(station1.getName(), station2.getName(), + PathType.DISTANCE.name()); + when(stationService.findIdByName(station1.getName())).thenReturn(station1.getId()); + when(stationService.findIdByName(station2.getName())).thenReturn(station2.getId()); + when(lineService.findAll()).thenReturn(null); + assertThatThrownBy(() -> pathService.findPath(request)).isInstanceOf( + NotFoundLineException.class); + } +} \ No newline at end of file