Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

디바이스 토큰 관련 테스트 코드 리팩토링 #491

Merged
merged 9 commits into from
Oct 2, 2023
Original file line number Diff line number Diff line change
@@ -1,113 +1,68 @@
package com.ddang.ddang.device.application;

import com.ddang.ddang.configuration.IsolateDatabase;
import com.ddang.ddang.device.application.dto.PersistDeviceTokenDto;
import com.ddang.ddang.device.application.fixture.DeviceTokenServiceFixture;
import com.ddang.ddang.device.domain.DeviceToken;
import com.ddang.ddang.device.infrastructure.persistence.JpaDeviceTokenRepository;
import com.ddang.ddang.image.domain.ProfileImage;
import com.ddang.ddang.user.application.exception.UserNotFoundException;
import com.ddang.ddang.user.domain.User;
import com.ddang.ddang.user.infrastructure.persistence.JpaUserRepository;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

@IsolateDatabase
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@SuppressWarnings("NonAsciiCharacters")
class DeviceTokenServiceTest {
class DeviceTokenServiceTest extends DeviceTokenServiceFixture {

@Autowired
DeviceTokenService deviceTokenService;

@Autowired
JpaDeviceTokenRepository deviceTokenRepository;

@Autowired
JpaUserRepository userRepository;

@Test
void 사용자의_디바이스_토큰이_존재하지_않는다면_저장한다() {
// given
final String deviceTokenValue = "deviceToken";
final User user = User.builder()
.name("사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12345")
.build();
userRepository.save(user);

final PersistDeviceTokenDto persistDeviceTokenDto = new PersistDeviceTokenDto(deviceTokenValue);

// when & then
assertThatNoException().isThrownBy(() -> deviceTokenService.persist(user.getId(), persistDeviceTokenDto));
assertThatNoException().isThrownBy(
() -> deviceTokenService.persist(디바이스_토큰이_없는_사용자.getId(), 디바이스_토큰_저장을_위한_DTO)
);
}

@Test
void 사용자의_디바이스_토큰이_이미_존재하고_새로운_토큰이_주어진다면_토큰을_갱신한다() {
// given
final String deviceTokenValue = "deviceToken";
final User user = User.builder()
.name("사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12345")
.build();
userRepository.save(user);

final DeviceToken deviceToken = new DeviceToken(user, deviceTokenValue);
deviceTokenRepository.save(deviceToken);

final String newDeviceTokenValue = "newDeviceToken";
final PersistDeviceTokenDto persistDeviceTokenDto = new PersistDeviceTokenDto(newDeviceTokenValue);

// when
deviceTokenService.persist(user.getId(), persistDeviceTokenDto);
deviceTokenService.persist(디바이스_토큰이_있는_사용자.getId(), 디바이스_토큰_갱신을_위한_DTO);

// then
assertThat(deviceToken.getDeviceToken()).isEqualTo(newDeviceTokenValue);
final Optional<DeviceToken> deviceTokenResult = deviceTokenRepository.findByUserId(디바이스_토큰이_있는_사용자.getId());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

질문

검사하는 대상의 변수명은 actual로 하기로 했던 것 같은데 조금 헷갈리네요,,

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 하고자 하는 메서드는 when 절에 있는데 해당 메서드는 반환값이 없기 때문에 then 절에서 직접 다시 조회해 온 후 테스트를 진행하는지라 actual을 사용하지 않았습니다. 이런 부분에도 actual을 사용하는 것이 좋을까요? 다른 분들의 의견도 궁금하군요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그런데 생각해보니 actual이 맞는 것 같네요. 수정하도록 하겠습니다!

final String actual = deviceTokenResult.get().getDeviceToken();

assertThat(actual).isEqualTo(갱신된_디바이스_토큰_값);
}

@Test
void 사용자의_디바이스_토큰이_이미_존재하고_동일한_토큰이_주어진다면_토큰을_갱신하지_않는다() {
// given
final String deviceTokenValue = "deviceToken";
final User user = User.builder()
.name("사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12345")
.build();
userRepository.save(user);

final DeviceToken deviceToken = new DeviceToken(user, deviceTokenValue);
deviceTokenRepository.save(deviceToken);

final String newDeviceTokenValue = deviceTokenValue;
final PersistDeviceTokenDto persistDeviceTokenDto = new PersistDeviceTokenDto(newDeviceTokenValue);

// when
deviceTokenService.persist(user.getId(), persistDeviceTokenDto);
deviceTokenService.persist(디바이스_토큰이_있는_사용자.getId(), 존재하는_디바이스_토큰과_동일한_토큰을_저장하려는_DTO);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

질문

저는 지토 코드를 참고해 Dto를 Dto라는 이름 없이 설명만 작성해주었는데 dto를 붙일지 여부도 통일시키면 좋을까요?

엔초가 작성해주신 방식이 가독성이 더 좋은 것 같다는 의견이긴 합니다..!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

통일하면 좋을 것 같아서 내일 데일리에 물어보도록 하죠!


// then
assertThat(deviceToken.getDeviceToken()).isEqualTo(deviceTokenValue);
final Optional<DeviceToken> userDeviceToken = deviceTokenRepository.findByUserId(디바이스_토큰이_있는_사용자.getId());
final String actual = userDeviceToken.get().getDeviceToken();

assertThat(actual).isEqualTo(사용_중인_디바이스_토큰_값);
}

@Test
void 사용자를_찾을_수_없다면_예외가_발생한다() {
// given
final Long invalidUserId = -999L;
final String deviceTokenValue = "deviceToken";
final PersistDeviceTokenDto persistDeviceTokenDto = new PersistDeviceTokenDto(deviceTokenValue);

// when & then
assertThatThrownBy(() -> deviceTokenService.persist(invalidUserId, persistDeviceTokenDto))
assertThatThrownBy(() -> deviceTokenService.persist(존재하지_않는_사용자_아이디, 디바이스_토큰_저장을_위한_DTO))
.isInstanceOf(UserNotFoundException.class)
.hasMessage("해당 사용자를 찾을 수 없습니다.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.ddang.ddang.device.application.fixture;

import com.ddang.ddang.device.application.dto.PersistDeviceTokenDto;
import com.ddang.ddang.device.domain.DeviceToken;
import com.ddang.ddang.device.infrastructure.persistence.JpaDeviceTokenRepository;
import com.ddang.ddang.image.domain.ProfileImage;
import com.ddang.ddang.user.domain.User;
import com.ddang.ddang.user.infrastructure.persistence.JpaUserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@SuppressWarnings("NonAsciiCharacters")
public class DeviceTokenServiceFixture {

@Autowired
private JpaDeviceTokenRepository deviceTokenRepository;

@Autowired
private JpaUserRepository userRepository;
private String 초기_디바이스_토큰_값 = "initialDeviceToken";
private DeviceToken 사용자의_디바이스_토큰;

protected String 사용_중인_디바이스_토큰_값 = "usingDeviceToken";
protected String 갱신된_디바이스_토큰_값 = "newDeviceToken";
protected Long 존재하지_않는_사용자_아이디 = -999L;
protected User 디바이스_토큰이_있는_사용자;
protected User 디바이스_토큰이_없는_사용자;
protected PersistDeviceTokenDto 디바이스_토큰_저장을_위한_DTO;
protected PersistDeviceTokenDto 디바이스_토큰_갱신을_위한_DTO;
protected PersistDeviceTokenDto 존재하는_디바이스_토큰과_동일한_토큰을_저장하려는_DTO;

@BeforeEach
void setUp() {
디바이스_토큰이_있는_사용자 = User.builder()
.name("디바이스 토큰이 있는 사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12345")
.build();
디바이스_토큰이_없는_사용자 = User.builder()
.name("디바이스 토큰이 없는 사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12346")
.build();
사용자의_디바이스_토큰 = new DeviceToken(디바이스_토큰이_있는_사용자, 사용_중인_디바이스_토큰_값);
userRepository.saveAll(List.of(디바이스_토큰이_있는_사용자, 디바이스_토큰이_없는_사용자));
deviceTokenRepository.save(사용자의_디바이스_토큰);

디바이스_토큰_저장을_위한_DTO = new PersistDeviceTokenDto(초기_디바이스_토큰_값);
디바이스_토큰_갱신을_위한_DTO = new PersistDeviceTokenDto(갱신된_디바이스_토큰_값);
존재하는_디바이스_토큰과_동일한_토큰을_저장하려는_DTO = new PersistDeviceTokenDto(사용_중인_디바이스_토큰_값);
}
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
package com.ddang.ddang.device.domain;

import com.ddang.ddang.image.domain.ProfileImage;
import com.ddang.ddang.user.domain.User;
import com.ddang.ddang.device.domain.fixture.DeviceTokenFixture;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class DeviceTokenTest {
@SuppressWarnings("NonAsciiCharacters")
class DeviceTokenTest extends DeviceTokenFixture {


@Test
void 디바이스_토큰이_다르다면_참을_반환한다() {
// given
final String deviceTokenValue = "deviceToken";
final User user = User.builder()
.name("사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12345")
.build();
final DeviceToken deviceToken = new DeviceToken(user, deviceTokenValue);

final String targetDeviceTokenValue = "differentDeviceToken";
final DeviceToken deviceToken = new DeviceToken(사용자, 디바이스_토큰);

// when
final boolean actual = deviceToken.isDifferentToken(targetDeviceTokenValue);
final boolean actual = deviceToken.isDifferentToken(새로운_디바이스_토큰);

// then
assertThat(actual).isTrue();
Expand All @@ -32,19 +24,10 @@ class DeviceTokenTest {
@Test
void 디바이스_토큰이_같다면_거짓을_반환한다() {
// given
final String deviceTokenValue = "deviceToken";
final User user = User.builder()
.name("사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12345")
.build();
final DeviceToken deviceToken = new DeviceToken(user, deviceTokenValue);

final String targetDeviceTokenValue = deviceTokenValue;
final DeviceToken deviceToken = new DeviceToken(사용자, 디바이스_토큰);

// when
final boolean actual = deviceToken.isDifferentToken(targetDeviceTokenValue);
final boolean actual = deviceToken.isDifferentToken(디바이스_토큰);

// then
assertThat(actual).isFalse();
Expand All @@ -53,21 +36,12 @@ class DeviceTokenTest {
@Test
void 디바이스_토큰을_갱신한다() {
// given
final String deviceTokenValue = "deviceToken";
final User user = User.builder()
.name("사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12345")
.build();
final DeviceToken deviceToken = new DeviceToken(user, deviceTokenValue);

final String newDeviceTokenValue = "newDeviceToken";
final DeviceToken deviceToken = new DeviceToken(사용자, 디바이스_토큰);

// when
deviceToken.updateDeviceToken(newDeviceTokenValue);
deviceToken.updateDeviceToken(새로운_디바이스_토큰);

// then
assertThat(deviceToken.getDeviceToken()).isEqualTo(newDeviceTokenValue);
assertThat(deviceToken.getDeviceToken()).isEqualTo(새로운_디바이스_토큰);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.ddang.ddang.device.domain.fixture;

import com.ddang.ddang.image.domain.ProfileImage;
import com.ddang.ddang.user.domain.User;
import org.junit.jupiter.api.BeforeEach;

@SuppressWarnings("NonAsciiCharacters")
public class DeviceTokenFixture {

protected String 디바이스_토큰 = "deviceToken";
protected String 새로운_디바이스_토큰 = "newDeviceToken";
protected User 사용자;

@BeforeEach
void setUp() {
사용자 = User.builder()
.name("사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12345")
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
import com.ddang.ddang.configuration.JpaConfiguration;
import com.ddang.ddang.configuration.QuerydslConfiguration;
import com.ddang.ddang.device.domain.DeviceToken;
import com.ddang.ddang.image.domain.ProfileImage;
import com.ddang.ddang.user.domain.User;
import com.ddang.ddang.user.infrastructure.persistence.JpaUserRepository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import com.ddang.ddang.device.infrastructure.persistence.fixture.JpaDeviceTokenRepositoryFixture;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
Expand All @@ -20,43 +16,20 @@
import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
@Import({JpaConfiguration.class, QuerydslConfiguration.class})
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@SuppressWarnings("NonAsciiCharacters")
@Import({JpaConfiguration.class, QuerydslConfiguration.class})
class JpaDeviceTokenRepositoryTest {

@PersistenceContext
EntityManager em;

@Autowired
JpaUserRepository userRepository;
class JpaDeviceTokenRepositoryTest extends JpaDeviceTokenRepositoryFixture {

@Autowired
JpaDeviceTokenRepository userDeviceTokenRepository;

@Test
void 주어진_사용자_아이디에_해당하는_기기토큰을_조회한다() {
// given
final String deviceToken = "token1234";

final User user = User.builder()
.name("사용자")
.profileImage(new ProfileImage("upload.png", "store.png"))
.reliability(4.7d)
.oauthId("12345")
.build();
userRepository.save(user);

final DeviceToken expect = new DeviceToken(user, deviceToken);
userDeviceTokenRepository.save(expect);

em.flush();
em.clear();

// when
final Optional<DeviceToken> actual = userDeviceTokenRepository.findByUserId(user.getId());
final Optional<DeviceToken> actual = userDeviceTokenRepository.findByUserId(사용자.getId());

// then
assertThat(actual).contains(expect);
assertThat(actual).contains(사용자의_디바이스_토큰);
}
}
Loading
Loading