Skip to content

Commit

Permalink
test: 테스트 커버리지 향상 (#62)
Browse files Browse the repository at this point in the history
* test: 인증 서비스 단위 테스트 추가

* fix: 테스트 커버리지 향상

* fix: 차량 테스트 커버리지 향상

* fix: 멤버 테스트 커버리지 향상

* test: 주유소 테스트 커버리지 향상

* fix: 시험장 테스트 커버리지 향상

* test: 테스트 커버리지 향상
  • Loading branch information
gengminy authored Dec 14, 2023
1 parent 3e89b37 commit d38ca12
Show file tree
Hide file tree
Showing 22 changed files with 530 additions and 104 deletions.
4 changes: 2 additions & 2 deletions src/main/java/com/testcar/car/domains/car/CarService.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ public Car updateById(Long carId, RegisterCarRequest request) {
if (!car.getName().equals(request.getName())) {
validateNameNotDuplicated(request.getName());
}
final Car updateMember = createEntity(request);
car.update(updateMember);
final Car updateCar = createEntity(request);
car.update(updateCar);
return carRepository.save(car);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public Expense register(Member member, RegisterExpenseRequest request) {
.amount(request.getAmount())
.usedAt(request.getUsedAt())
.build();
if (request.getStockNumber() != null && !request.getStockNumber().isBlank()) {
if (request.getStockNumber() != null) {
final CarStock carStock = carStockService.findByStockNumber(request.getStockNumber());
expense.updateCarStock(carStock);
}
Expand All @@ -62,8 +62,8 @@ public Expense update(Member member, Long expenseId, RegisterExpenseRequest requ

if (updateStockNumber == null) {
expense.updateCarStock(null);
} else if (!Objects.equals(expenseDto.getStockNumber(), request.getStockNumber())) {
final CarStock carStock = carStockService.findByStockNumber(request.getStockNumber());
} else if (!Objects.equals(expenseDto.getStockNumber(), updateStockNumber)) {
final CarStock carStock = carStockService.findByStockNumber(updateStockNumber);
expense.updateCarStock(carStock);
}
expense.updateMemberBy(member);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
import com.testcar.car.domains.trackReservation.repository.TrackReservationSlotRepository;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -37,33 +36,32 @@ public Set<TrackReservationSlot> findAllByTrackIdAndDate(Long trackId, LocalDate
public List<TrackReservationSlot> reserve(
Track track, TrackReservation trackReservation, TrackReservationRequest request) {
this.validateReservationSlots(request.getDate(), request.getReservationSlots());
final List<ReservationSlotVo> slots = request.getReservationSlots();

final Map<LocalDateTime, TrackReservationSlot> existSlotMap =
this.findAllExistedSlotMap(track.getId(), request.getDate());
slots.forEach(slot -> this.validateSlotNotDuplicated(slot, existSlotMap));

final List<TrackReservationSlot> reservations =
slots.stream().map(slot -> createEntity(track, trackReservation, slot)).toList();
return trackReservationSlotRepository.saveAll(reservations);
}

/** 예약하려는 시간과 DB에 존재하는 예약 시간 슬롯 Map 을 비교하여 중복을 검증한다 */
private Map<LocalDateTime, TrackReservationSlot> findAllExistedSlotMap(
Long trackId, LocalDate date) {
final Set<TrackReservationSlot> existedSlots =
trackReservationSlotRepository.findAllByTrackIdAndDate(trackId, date);
return existedSlots.stream()
.collect(Collectors.toMap(TrackReservationSlot::getStartedAt, Function.identity()));
trackReservationSlotRepository.findAllByTrackIdAndDate(
track.getId(), request.getDate());
validateSlotNotDuplicated(existedSlots, request.getReservationSlots());

final Set<TrackReservationSlot> newReservationSlots =
request.getReservationSlots().stream()
.map(slot -> createEntity(track, trackReservation, slot))
.collect(Collectors.toSet());
return trackReservationSlotRepository.saveAll(newReservationSlots);
}

/** 예약하려는 시간과 DB에 존재하는 예약 시간 슬롯을 비교하여 중복을 검증한다 */
private void validateSlotNotDuplicated(
ReservationSlotVo slot, Map<LocalDateTime, TrackReservationSlot> existSlotMap) {
if (existSlotMap.containsKey(slot.getStartedAt())
&& existSlotMap
.get(slot.getStartedAt())
.getExpiredAt()
.equals(slot.getExpiredAt())) {
Set<TrackReservationSlot> slots1, List<ReservationSlotVo> slots2) {
final Set<ReservationSlotVo> slots1Set =
slots1.stream()
.map(
slot ->
ReservationSlotVo.builder()
.startedAt(slot.getStartedAt())
.expiredAt(slot.getExpiredAt())
.build())
.collect(Collectors.toSet());
if (!Collections.disjoint(slots1Set, slots2)) {
throw new BadRequestException(ALREADY_RESERVED_SLOT);
}
}
Expand All @@ -89,6 +87,8 @@ private void validateReservationSlot(LocalDate date, ReservationSlotVo slot) {
final LocalDateTime expiredAt = slot.getExpiredAt();

validateAfterNow(startedAt);
validateTimeNotNull(startedAt);
validateTimeNotNull(expiredAt);
validateTimeAfter(startedAt, expiredAt);

if (!startedAt.toLocalDate().equals(date)) {
Expand All @@ -103,10 +103,13 @@ private void validateAfterNow(LocalDateTime time) {
}
}

private void validateTimeAfter(LocalDateTime startedAt, LocalDateTime expiredAt) {
if (startedAt == null || expiredAt == null) {
private void validateTimeNotNull(LocalDateTime time) {
if (time == null) {
throw new BadRequestException(EMPTY_RESERVATION_SLOT);
}
}

private void validateTimeAfter(LocalDateTime startedAt, LocalDateTime expiredAt) {
if (expiredAt.isBefore(startedAt)) {
throw new BadRequestException(INVALID_RESERVATION_SLOT);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;

@Getter
@Builder
@EqualsAndHashCode
public class ReservationSlotVo {
@DateTimeFormat
@NotNull(message = "예약 시간을 입력해주세요.")
Expand Down
6 changes: 6 additions & 0 deletions src/test/java/com/testcar/car/common/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ private Constant() {}
LocalDateTime.now().withHour(12).withMinute(0).withSecond(0).withNano(0);

public static final LocalDateTime TOMORROW = NOW.plusDays(1L);
public static final LocalDateTime DAY_AFTER_TOMORROW = NOW.plusDays(2L);
public static final LocalDateTime YESTERDAY = NOW.minusDays(1L);

/** Member */
Expand All @@ -23,6 +24,7 @@ private Constant() {}
public static final String MEMBER_EMAIL = "[email protected]";
public static final String ANOTHER_MEMBER_EMAIL = "[email protected]";
public static final String MEMBER_PASSWORD = "1234abcd@";
public static final String ANOTHER_MEMBER_PASSWORD = "dcba4321@";
public static final Role MEMBER_ROLE = Role.ADMIN;
public static final String DEPARTMENT_NAME = "모비스시스템팀";

Expand All @@ -47,7 +49,11 @@ private Constant() {}
public static final double TRACK_LENGTH = 1230.6;
public static final LocalDate TRACK_RESERVATION_DATE = TOMORROW.toLocalDate();
public static final LocalDateTime TRACK_RESERVATION_SLOT_STARTED_AT = TOMORROW.withHour(11);
public static final LocalDateTime ANOTHER_TRACK_RESERVATION_SLOT_STARTED_AT =
TOMORROW.withHour(12);
public static final LocalDateTime TRACK_RESERVATION_SLOT_EXPIRED_AT = TOMORROW.withHour(12);
public static final LocalDateTime ANOTHER_TRACK_RESERVATION_SLOT_EXPIRED_AT =
TOMORROW.withHour(13);

/** Gas Station */
public static final String GAS_STATION_NAME = "서산주유소A";
Expand Down
20 changes: 18 additions & 2 deletions src/test/java/com/testcar/car/common/TrackEntityFactory.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.testcar.car.common;

import static com.testcar.car.common.Constant.ANOTHER_TRACK_RESERVATION_SLOT_EXPIRED_AT;
import static com.testcar.car.common.Constant.ANOTHER_TRACK_RESERVATION_SLOT_STARTED_AT;
import static com.testcar.car.common.Constant.TRACK_DESCRIPTION;
import static com.testcar.car.common.Constant.TRACK_LENGTH;
import static com.testcar.car.common.Constant.TRACK_LOCATION;
Expand Down Expand Up @@ -54,13 +56,27 @@ public static TrackReservationSlot createTrackReservationSlot(
.build();
}

public static TrackReservationSlot createAnotherTrackReservationSlot(
TrackReservation trackReservation) {
return createTrackReservationSlotBuilder()
.trackReservation(trackReservation)
.startedAt(ANOTHER_TRACK_RESERVATION_SLOT_STARTED_AT)
.expiredAt(ANOTHER_TRACK_RESERVATION_SLOT_EXPIRED_AT)
.build();
}

public static TrackReservationSlot.TrackReservationSlotBuilder
createTrackReservationSlotBuilder() {
return TrackReservationSlot.builder().trackReservation(createTrackReservation());
}

public static Set<TrackReservationSlot> createTrackReservationSlotSet() {
final TrackReservation trackReservation = createTrackReservation();
public static Set<TrackReservationSlot> createTrackReservationSlotSet(
TrackReservation trackReservation) {
return Set.of(createTrackReservationSlot(trackReservation));
}

public static Set<TrackReservationSlot> createAnotherTrackReservationSlotSet(
TrackReservation trackReservation) {
return Set.of(createAnotherTrackReservationSlot(trackReservation));
}
}
86 changes: 86 additions & 0 deletions src/test/java/com/testcar/car/domains/auth/AuthServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.testcar.car.domains.auth;

import static com.testcar.car.common.Constant.MEMBER_PASSWORD;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;

import com.testcar.car.common.MemberEntityFactory;
import com.testcar.car.common.auth.JwtService;
import com.testcar.car.common.exception.NotFoundException;
import com.testcar.car.common.exception.UnauthorizedException;
import com.testcar.car.domains.auth.model.LoginRequest;
import com.testcar.car.domains.auth.request.AuthRequestFactory;
import com.testcar.car.domains.auth.util.PasswordEncoder;
import com.testcar.car.domains.member.entity.Member;
import com.testcar.car.domains.member.repository.MemberRepository;
import java.util.Optional;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class AuthServiceTest {
@Mock private JwtService jwtService;
@Mock private MemberRepository memberRepository;
@InjectMocks private AuthService authService;

private static Member member;
private static final String encodedPassword = PasswordEncoder.encode(MEMBER_PASSWORD);
private static final String token = "generatedToken";

@BeforeAll
public static void setUp() {
member = MemberEntityFactory.createMemberBuilder().password(encodedPassword).build();
}

@Test
public void 로그인_성공_테스트() {
// given
final LoginRequest request = AuthRequestFactory.createLoginRequest();
when(memberRepository.findByEmailAndDeletedFalse(request.getEmail()))
.thenReturn(Optional.of(member));
when(jwtService.generateAccessToken(member.getId())).thenReturn(token);

// when
String result = authService.login(request);

// then
assertNotNull(result);
assertEquals(token, result);
}

@Test
public void 해당_아이디의_사용자가_DB에_존재하지_않으면_예외가_발생한다() {
// given
final LoginRequest request = AuthRequestFactory.createLoginRequest();
when(memberRepository.findByEmailAndDeletedFalse(request.getEmail()))
.thenReturn(Optional.empty());

// when, then
assertThrows(
NotFoundException.class,
() -> {
authService.login(request);
});
}

@Test
public void 잘못된_비밀번호를_입력하면_예외가_발생한다() {
// given
final LoginRequest invaildRequest = AuthRequestFactory.createInvalidLoginRequest();
when(memberRepository.findByEmailAndDeletedFalse(invaildRequest.getEmail()))
.thenReturn(Optional.of(member));

// when, then
assertThrows(
UnauthorizedException.class,
() -> {
authService.login(invaildRequest);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.testcar.car.domains.auth.request;

import static com.testcar.car.common.Constant.ANOTHER_MEMBER_PASSWORD;
import static com.testcar.car.common.Constant.MEMBER_EMAIL;
import static com.testcar.car.common.Constant.MEMBER_PASSWORD;

import com.testcar.car.domains.auth.model.LoginRequest;

public class AuthRequestFactory {
private AuthRequestFactory() {}

public static LoginRequest createLoginRequest() {
return LoginRequest.builder().email(MEMBER_EMAIL).password(MEMBER_PASSWORD).build();
}

public static LoginRequest createInvalidLoginRequest() {
return LoginRequest.builder().email(MEMBER_EMAIL).password(ANOTHER_MEMBER_PASSWORD).build();
}
}
33 changes: 25 additions & 8 deletions src/test/java/com/testcar/car/domains/car/CarServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import com.testcar.car.domains.car.request.CarRequestFactory;
import java.util.Optional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
Expand All @@ -39,8 +39,8 @@ public class CarServiceTest {
private static Car car;
private static final Long carId = 1L;

@BeforeAll
public static void setUp() {
@BeforeEach
public void setUp() {
car = CarEntityFactory.createCar();
}

Expand Down Expand Up @@ -101,19 +101,36 @@ public static void setUp() {
}

@Test
void 차량정보를_수정한다() {
void 차량이름이_다를_경우_차량정보를_함께_수정한다() {
// given
RegisterCarRequest request = CarRequestFactory.createRegisterCarRequest();
RegisterCarRequest request = CarRequestFactory.createRegisterCarRequest(ANOTHER_CAR_NAME);
when(carRepository.findByIdAndDeletedFalse(carId)).thenReturn(Optional.of(car));
when(carRepository.existsByNameAndDeletedFalse(request.getName())).thenReturn(false);
given(carRepository.save(any(Car.class))).willReturn(car);

// when
Car newCar = carService.updateById(carId, request);

// then
assertNotNull(newCar);
verify(carRepository).findByIdAndDeletedFalse(carId);
then(carRepository).should().save(any(Car.class));
}

@Test
void 차량이름이_같을_경우_나머지_정보만_수정한다() {
// given
RegisterCarRequest request = CarRequestFactory.createRegisterCarRequest();
when(carRepository.findByIdAndDeletedFalse(carId)).thenReturn(Optional.of(car));
given(carRepository.save(any(Car.class))).willReturn(car);

// when
Car newCar = carService.updateById(carId, request);

// then
assertNotNull(newCar);
verify(carRepository).findByIdAndDeletedFalse(carId);
then(carRepository).should().save(any(Car.class));
}

@Test
Expand All @@ -123,7 +140,7 @@ public static void setUp() {
when(carRepository.findByIdAndDeletedFalse(carId)).thenReturn(Optional.of(car));
when(carRepository.existsByNameAndDeletedFalse(request.getName())).thenReturn(true);

// when
// when, then
Assertions.assertThrows(
BadRequestException.class,
() -> {
Expand All @@ -142,9 +159,9 @@ public static void setUp() {
Car deletedCar = carService.deleteById(carId);

// then
verify(carRepository).findByIdAndDeletedFalse(carId);
then(carRepository).should().save(any(Car.class));
assertNotNull(deletedCar);
assertTrue(deletedCar.getDeleted());
verify(carRepository).findByIdAndDeletedFalse(carId);
then(carRepository).should().save(any(Car.class));
}
}
Loading

0 comments on commit d38ca12

Please sign in to comment.