이상적으로, 각 테스트 케이스는 서로 분리되어야 한다. 이를 위해 가짜 객체(Mock object)를 생성하는 것도 좋은 방법이다.
출처: 단위 테스트 (위키백과)
분리 되기 어려운 클래스들

가짜객체 (Mock object) 를 통한 분리 방법

Mock 직접 구현
import com.sparta.springcore.dto.ProductMypriceRequestDto;
import com.sparta.springcore.dto.ProductRequestDto;
import com.sparta.springcore.model.Product;
import java.util.List;
public class MockProductService {
private final MockProductRepository mockProductRepository;
public static final int MIN_MY_PRICE = 100;
public MockProductService() {
this.mockProductRepository = new MockProductRepository();
}
public Product createProduct(ProductRequestDto requestDto, Long userId ) {
// 요청받은 DTO 로 DB에 저장할 객체 만들기
Product product = new Product(requestDto, userId);
mockProductRepository.save(product);
return product;
}
public Product updateProduct(Long id, ProductMypriceRequestDto requestDto) {
int myprice = requestDto.getMyprice();
if (myprice < MIN_MY_PRICE) {
throw new IllegalArgumentException("유효하지 않은 관심 가격입니다. 최소 " + MIN_MY_PRICE + " 원 이상으로 설정해 주세요.");
}
Product product = mockProductRepository.findById(id)
.orElseThrow(() -> new NullPointerException("해당 아이디가 존재하지 않습니다."));
product.setMyprice(myprice);
mockProductRepository.save(product);
return product;
}
// 회원 ID 로 등록된 상품 조회
public List<Product> getProducts(Long userId) {
return mockProductRepository.findAllByUserId(userId);
}
// (관리자용) 상품 전체 조회
public List<Product> getAllProducts() {
return mockProductRepository.findAll();
}
}import com.sparta.springcore.model.Product;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class MockProductRepository {
private List<Product> products = new ArrayList<>();
// 상품 테이블 ID: 1부터 시작
private Long productId = 1L;
// 상품 저장
public Product save(Product product) {
for (Product existProduct : products) {
// 이미 저장된 상품 -> 희망 최저가 업데이트
if (existProduct.getId().equals(product.getId())) {
int myprice = product.getMyprice();
existProduct.setMyprice(myprice);
return existProduct;
}
}
// 신규 상품 -> DB 에 저장
product.setId(productId);
++productId;
products.add(product);
return product;
}
// 상품 ID 로 상품 조회
public Optional<Product> findById(Long id) {
for (Product product : products) {
if (product.getId().equals(id)) {
return Optional.of(product);
}
}
return Optional.empty();
}
// 회원 ID 로 등록된 상품 조회
public List<Product> findAllByUserId(Long userId) {
List<Product> userProducts = new ArrayList<>();
for (Product product : products) {
if (product.getId().equals(userId)) {
userProducts.add(product);
}
}
return userProducts;
}
// (관리자용) 상품 전체 조회
public List<Product> findAll() {
return products;
}
}import com.sparta.springcore.dto.ProductMypriceRequestDto;
import com.sparta.springcore.dto.ProductRequestDto;
import com.sparta.springcore.model.Product;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static com.sparta.springcore.service.ProductService.MIN_MY_PRICE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class MockProductServiceTest {
@Test
@DisplayName("관심 상품 희망가 - 최저가 이상으로 변경")
void updateProduct_Normal() {
// given
int myprice = MIN_MY_PRICE + 1000;
ProductMypriceRequestDto requestMyPriceDto = new ProductMypriceRequestDto(
myprice
);
Long userId = 777L;
ProductRequestDto requestProductDto = new ProductRequestDto(
"오리온 꼬북칩 초코츄러스맛 160g",
"https://shopping-phinf.pstatic.net/main_2416122/24161228524.20200915151118.jpg",
"https://search.shopping.naver.com/gate.nhn?id=24161228524",
2350
);
MockProductService mockProductService = new MockProductService();
// 회원의 관심상품을 생성
Product product = mockProductService.createProduct(requestProductDto, userId);
// when
Product result = mockProductService.updateProduct(product.getId(), requestMyPriceDto);
// then
assertEquals(myprice, result.getMyprice());
}
@Test
@DisplayName("관심 상품 희망가 - 최저가 미만으로 변경")
void updateProduct_Failed() {
// given
int myprice = MIN_MY_PRICE - 50;
ProductMypriceRequestDto requestMyPriceDto = new ProductMypriceRequestDto(
myprice
);
Long userId = 777L;
ProductRequestDto requestProductDto = new ProductRequestDto(
"오리온 꼬북칩 초코츄러스맛 160g",
"https://shopping-phinf.pstatic.net/main_2416122/24161228524.20200915151118.jpg",
"https://search.shopping.naver.com/gate.nhn?id=24161228524",
2350
);
MockProductService mockProductService = new MockProductService();
// 회원의 관심상품을 생성
Product product = mockProductService.createProduct(requestProductDto, userId);
// when
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
mockProductService.updateProduct(product.getId(), requestMyPriceDto);
});
// then
assertEquals(
"유효하지 않은 관심 가격입니다. 최소 " + MIN_MY_PRICE + " 원 이상으로 설정해 주세요.",
exception.getMessage()
);
}
}