테스트

This commit is contained in:
sejoung kim
2021-06-23 10:24:12 +09:00
parent 3fa86f5372
commit 25b5dead1e
28 changed files with 247 additions and 98 deletions

View File

@@ -1,6 +1,6 @@
plugins {
id 'java'
id 'org.springframework.boot' version '2.3.9.RELEASE'
id 'org.springframework.boot' version '2.5.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}

View File

@@ -1,19 +0,0 @@
package io.github.sejoung.product.entities;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
@ToString(callSuper = true)
@DiscriminatorValue(PeriodProductEntity.DISCRIMINATOR_VALUE)
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PeriodProductEntity extends ProductEntity{
public static final String DISCRIMINATOR_VALUE = "PERIOD";
}

View File

@@ -0,0 +1,5 @@
package io.github.sejoung.product.persistence.constants;
public enum ProductStatus {
CREATE, DELETE, TEMPORARY, PERMANENTLY_DELETE
}

View File

@@ -1,7 +1,8 @@
package io.github.sejoung.product.constants;
package io.github.sejoung.product.persistence.constants;
import io.github.sejoung.product.entities.PeriodProductEntity;
import io.github.sejoung.product.entities.RoundProductEntity;
import io.github.sejoung.product.persistence.entities.PeriodProductEntity;
import io.github.sejoung.product.persistence.entities.RoundProductEntity;
import lombok.Getter;
@Getter

View File

@@ -0,0 +1,36 @@
package io.github.sejoung.product.persistence.entities;
import java.time.LocalDate;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import io.github.sejoung.product.persistence.constants.ProductStatus;
import io.github.sejoung.product.persistence.constants.ProductType;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
@ToString(callSuper = true)
@DiscriminatorValue(PeriodProductEntity.DISCRIMINATOR_VALUE)
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PeriodProductEntity extends ProductEntity {
public static final String DISCRIMINATOR_VALUE = "PERIOD";
@Column
private LocalDate startDate;
@Column
private LocalDate endDate;
public PeriodProductEntity(String productName, Long categoryId, ProductStatus productStatus, LocalDate startDate,
LocalDate endDate) {
super(productName, ProductType.PERIOD, categoryId, productStatus);
this.startDate = startDate;
this.endDate = endDate;
}
}

View File

@@ -1,4 +1,4 @@
package io.github.sejoung.product.entities;
package io.github.sejoung.product.persistence.entities;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
@@ -12,9 +12,8 @@ import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import org.springframework.data.domain.AbstractAggregateRoot;
import io.github.sejoung.product.constants.ProductType;
import io.github.sejoung.product.persistence.constants.ProductStatus;
import io.github.sejoung.product.persistence.constants.ProductType;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -26,7 +25,7 @@ import lombok.ToString;
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString
public class ProductEntity extends AbstractAggregateRoot<ProductEntity> {
public abstract class ProductEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long productId;
@@ -38,11 +37,16 @@ public class ProductEntity extends AbstractAggregateRoot<ProductEntity> {
@Column(name = "product_type", nullable = false)
private ProductType productType;
@Enumerated(EnumType.STRING)
@Column
private ProductStatus productStatus;
private Long categoryId;
public ProductEntity(String productName, ProductType productType, Long categoryId) {
protected ProductEntity(String productName, ProductType productType, Long categoryId, ProductStatus productStatus) {
this.productName = productName;
this.productType = productType;
this.categoryId = categoryId;
this.productStatus = productStatus;
}
}

View File

@@ -1,10 +1,11 @@
package io.github.sejoung.product.entities;
package io.github.sejoung.product.persistence.entities;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import io.github.sejoung.product.constants.ProductType;
import io.github.sejoung.product.persistence.constants.ProductStatus;
import io.github.sejoung.product.persistence.constants.ProductType;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -21,9 +22,9 @@ public class RoundProductEntity extends ProductEntity {
@Column(name = "cnt", nullable = false)
private Integer count;
public RoundProductEntity(String productName, ProductType productType,
Long categoryId, Integer count) {
super(productName, productType, categoryId);
public RoundProductEntity(String productName,
Long categoryId, ProductStatus productStatus, Integer count) {
super(productName, ProductType.ROUND, categoryId, productStatus);
this.count = count;
}
}

View File

@@ -0,0 +1,25 @@
package io.github.sejoung.product.persistence.mapper;
import io.github.sejoung.product.entities.Category;
import io.github.sejoung.product.entities.Product;
import io.github.sejoung.product.entities.RoundProduct;
import io.github.sejoung.product.persistence.constants.ProductStatus;
import io.github.sejoung.product.persistence.entities.RoundProductEntity;
public interface RoundProductMapper {
static RoundProductEntity toEntity(RoundProduct product) {
return new RoundProductEntity(product.getProductName(), product.getCategory().getCategoryId(),
ProductStatus.valueOf(product.getStatus().name()),
product.getCount());
}
static RoundProduct toDto(RoundProductEntity entity) {
return new RoundProduct(entity.getProductId(), entity.getCategoryId(),
Category.ProductType.valueOf(entity.getProductType().name()),
Product.ProductStatus.valueOf(entity.getProductStatus().name()), entity.getProductName(),
entity.getCount());
}
}

View File

@@ -1,8 +1,8 @@
package io.github.sejoung.product.repository;
package io.github.sejoung.product.persistence.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import io.github.sejoung.product.entities.ProductEntity;
import io.github.sejoung.product.persistence.entities.ProductEntity;
public interface ProductRepository extends JpaRepository<ProductEntity, Long> {
}

View File

@@ -0,0 +1,25 @@
package io.github.sejoung.product.persistence.service;
import javax.transaction.Transactional;
import io.github.sejoung.product.entities.RoundProduct;
import io.github.sejoung.product.persistence.mapper.RoundProductMapper;
import io.github.sejoung.product.persistence.repository.ProductRepository;
import io.github.sejoung.product.usecases.port.out.SaveRoundProductOutUseCase;
public class SaveRoundProductService implements SaveRoundProductOutUseCase {
private final ProductRepository repository;
public SaveRoundProductService(ProductRepository repository) {
this.repository = repository;
}
@Transactional
@Override
public RoundProduct saveRoundProduct(RoundProduct product) {
var productEntity = RoundProductMapper.toEntity(product);
return RoundProductMapper.toDto(repository.save(productEntity));
}
}

View File

@@ -0,0 +1,11 @@
spring:
jpa:
show-sql: true
open-in-view: false
hibernate:
ddl-auto: create-drop
properties:
hibernate:
discriminator:
ignore_explicit_for_joined: true
database-platform: org.hibernate.dialect.H2Dialect

View File

@@ -1,4 +1,4 @@
package io.github.sejoung.product;
package io.github.sejoung.product.persistence;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@@ -0,0 +1,37 @@
package io.github.sejoung.product.persistence.repository;
import static org.assertj.core.api.Assertions.*;
import java.time.LocalDate;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import io.github.sejoung.product.persistence.constants.ProductStatus;
import io.github.sejoung.product.persistence.entities.PeriodProductEntity;
import io.github.sejoung.product.persistence.entities.RoundProductEntity;
@DataJpaTest
class ProductRepositoryTest {
@Autowired
private ProductRepository repository;
@Autowired
private TestEntityManager entityManager;
@DisplayName("조회기능 테스트")
@Test
void findAllTest() {
entityManager.persistAndFlush(new RoundProductEntity("회차권", 1L, ProductStatus.CREATE, 1));
entityManager.persistAndFlush(
new PeriodProductEntity("ad", 1L, ProductStatus.CREATE, LocalDate.now(), LocalDate.now().plusDays(1)));
var productEntities = repository.findAll();
assertThat(productEntities.size()).isEqualTo(2);
}
}

View File

@@ -0,0 +1,31 @@
package io.github.sejoung.product.persistence.service;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import io.github.sejoung.product.persistence.repository.ProductRepository;
import io.github.sejoung.product.persistence.util.TestUtil;
@DataJpaTest
class SaveRoundProductServiceTest {
@Autowired
private ProductRepository repository;
private SaveRoundProductService service;
@BeforeEach
void setUp() {
service = new SaveRoundProductService(repository);
}
@Test
void saveRoundProduct() {
var actual = service.saveRoundProduct(TestUtil.defaultRoundProduct());
assertThat(actual.getProductId()).isNotNull();
}
}

View File

@@ -0,0 +1,11 @@
package io.github.sejoung.product.persistence.util;
import io.github.sejoung.product.entities.Category;
import io.github.sejoung.product.entities.Product;
import io.github.sejoung.product.entities.RoundProduct;
public interface TestUtil {
static RoundProduct defaultRoundProduct() {
return new RoundProduct(null, 1L, Category.ProductType.ROUND, Product.ProductStatus.CREATE, "회차권", 2);
}
}

View File

@@ -1,29 +0,0 @@
package io.github.sejoung.product.repository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import io.github.sejoung.product.constants.ProductType;
import io.github.sejoung.product.entities.RoundProductEntity;
@DataJpaTest
class ProductRepositoryTest {
@Autowired
private ProductRepository repository;
@Autowired
private TestEntityManager entityManager;
@Test
void test() {
repository.saveAndFlush(new RoundProductEntity("회차권", ProductType.ROUND, 1L, 1));
repository.findAll().forEach(productEntity -> {
System.out.println(productEntity);
});
}
}

View File

@@ -7,11 +7,13 @@ jar {
}
dependencies {
implementation 'org.hibernate:hibernate-validator:7.0.1.Final'
implementation 'org.glassfish:jakarta.el:4.0.1'
implementation 'javax.validation:validation-api:2.0.1.Final'
implementation "org.mapstruct:mapstruct:1.4.2.Final"
annotationProcessor "org.mapstruct:mapstruct-processor:1.4.2.Final"
testImplementation 'org.hibernate:hibernate-validator:6.2.0.Final'
testImplementation 'org.glassfish:javax.el:3.0.0'
testAnnotationProcessor "org.mapstruct:mapstruct-processor:1.4.2.Final"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'

View File

@@ -1,6 +1,8 @@
package io.github.sejoung.product.entities;
import jakarta.validation.constraints.NotNull;
import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.ToString;

View File

@@ -2,7 +2,7 @@ package io.github.sejoung.product.entities;
import java.time.LocalDate;
import jakarta.validation.constraints.NotNull;
import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.ToString;

View File

@@ -3,12 +3,13 @@ package io.github.sejoung.product.entities;
import java.time.LocalDateTime;
import java.util.Set;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

View File

@@ -1,7 +1,9 @@
package io.github.sejoung.product.entities;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import lombok.Getter;
import lombok.ToString;

View File

@@ -2,20 +2,16 @@ package io.github.sejoung.product.mapper;
import io.github.sejoung.product.entities.RoundProduct;
import io.github.sejoung.product.usecases.port.in.SaveRoundProductInUseCase;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public abstract class SaveRoundProductCommandMapper {
public static SaveRoundProductInUseCase.SaveRoundProductCommand toDto(RoundProduct roundProduct) {
public interface SaveRoundProductCommandMapper {
static SaveRoundProductInUseCase.SaveRoundProductCommand toDto(RoundProduct roundProduct) {
return new SaveRoundProductInUseCase.SaveRoundProductCommand(roundProduct.getProductId(),
roundProduct.getCategory().getCategoryId(), roundProduct.getCategory().getProductType(),
roundProduct.getStatus(), roundProduct.getProductName(), roundProduct.getCount());
}
public static RoundProduct toEntity(SaveRoundProductInUseCase.SaveRoundProductCommand command) {
static RoundProduct toEntity(SaveRoundProductInUseCase.SaveRoundProductCommand command) {
return new RoundProduct(command.getProductId(), command.getCategoryId(), command.getProductType(),
command.getStatus(), command.getProductName(), command.getCount());
}

View File

@@ -1,12 +1,14 @@
package io.github.sejoung.product.usecases.port.in;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import io.github.sejoung.product.entities.Category;
import io.github.sejoung.product.entities.Product;
import io.github.sejoung.product.validating.SelfValidating;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.EqualsAndHashCode;
import lombok.Getter;

View File

@@ -1,8 +1,8 @@
package io.github.sejoung.product.validating;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
public abstract class SelfValidating<T> {

View File

@@ -4,10 +4,12 @@ import static org.junit.jupiter.api.Assertions.*;
import java.time.LocalDate;
import javax.validation.ConstraintViolationException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import jakarta.validation.ConstraintViolationException;
class PeriodProductTest {

View File

@@ -2,10 +2,12 @@ package io.github.sejoung.product.entities;
import static org.junit.jupiter.api.Assertions.*;
import javax.validation.ConstraintViolationException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import jakarta.validation.ConstraintViolationException;
class RoundProductTest {

View File

@@ -2,12 +2,14 @@ package io.github.sejoung.product.usecases.port.in;
import static org.junit.jupiter.api.Assertions.*;
import javax.validation.ConstraintViolationException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import io.github.sejoung.product.entities.Category;
import io.github.sejoung.product.entities.Product;
import jakarta.validation.ConstraintViolationException;
class SaveRoundProductInUseCaseTest {

View File

@@ -1,7 +1,6 @@
package io.github.sejoung.product.usecases.service;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -26,6 +25,6 @@ class SaveRoundProductServiceTest {
var command = new SaveRoundProductInUseCase.SaveRoundProductCommand(null, 1L, Category.ProductType.ROUND,
Product.ProductStatus.CREATE, "2회권", 2);
var actual = service.save(command);
assertEquals(99, actual.getProductId());
Assertions.assertEquals(99, actual.getProductId());
}
}