TIL day 43 - MultipartFile

최병은·2024년 2월 27일
  1. 메뉴 통합 테스트 작성
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class MenuServiceIntegrationTest {

    @Autowired
    MenuService menuService;
    @Autowired
    MenuRepository menuRepository;
    @Autowired
    UploadService uploadService;
    @Autowired
    StoreRepository storeRepository;

    Long createdId;

    UserDetailsImpl userDetails = new UserDetailsImpl(
            new User("asdf1234",
                    "asdfA1234!",
                    "경기도", "asd@email.com", UserRoleEnum.SELLER));

    @Test
    @Order(1)
    @DisplayName("메뉴 등록하기")
    void test1() throws IOException {
        // given
        Long storeId = 1L;
        String menuName = "탕수육";
        int menuPrice = 25000;
        String menuDescription = "돼지고기 : 국내산";

        MockMultipartFile image = new MockMultipartFile(
                "test",
                "a.png",
                "image/png",
                new FileInputStream(new File("C:/Users/Owner/Pictures/Screenshots/a.png")));

        MenuRequest requestDto = new MenuRequest(menuName, menuPrice, menuDescription, image);

        // when - then
        menuService.createMenu(storeId, requestDto, userDetails);

        List<MenuResponse> menus = menuService.getMenus();
        MenuResponse createdMenu = menus.get(menus.size() - 1); // 가장 최근에 등록된 메뉴 가져오기
        this.createdId = createdMenu.getMenuId();

        assertNotNull(createdId);
    }

    @Test
    @Order(2)
    @DisplayName("메뉴 가격, 이미지 변경하기")
    void test2() throws IOException {
        // given
        Long menuId = createdId;
        String menuName = "탕수육";
        int menuPrice = 20000;
        String menuDescription = "돼지고기 : 국내산";

        MockMultipartFile image = new MockMultipartFile(
                "test2",
                "b.png",
                "image/png",
                new FileInputStream(new File("C:/Users/Owner/Pictures/Screenshots/b.png")));

        MenuRequest requestDto = new MenuRequest(menuName, menuPrice, menuDescription, image);

        // when - then
        menuService.updateMenu(menuId, requestDto, userDetails);
    }

    @Test
    @Order(3)
    @DisplayName("메뉴 가격, 이미지 변경되었는지 조회하기")
    void test3() {
        // given
        Long menuId = createdId;
        String imageUrl = "/uploads/b.png";
        int menuPrice = 20000;

        // when
        List<MenuResponse> menu = menuService.getMenuFindById(menuId);

        // then
        MenuResponse updatedMenu = menu.stream()
                .filter(menuResponse -> menuResponse.getMenuName().equals("탕수육"))
                .findFirst()
                .orElse(null);

        assertNotNull(menu);
        assertEquals(imageUrl, updatedMenu.getImageUrl());
        assertEquals(menuPrice, updatedMenu.getMenuPrice());
    }
}
@Service
public class UploadService {
    @Value("${image.upload-dir}")
    private String uploadDir;

    public String uploadImageAndGetUrl(MultipartFile image){
        try {
            // 파일 이름 생성
            String fileName = StringUtils.cleanPath(image.getOriginalFilename());
            // 저장할 경로
            Path targetLocation = Paths.get(uploadDir).resolve(fileName);
            // 파일 저장
            Files.copy(image.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

            String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
                    .path("/uploads/")
                    .path(fileName)
                    .toUriString();

//            String fileDownloadUri = "http://localhost:8080/uploads/" + fileName; //테스트 환경에서는 실제 HTTP 요청이 없기 때문에 테스트할 때 적용

            return fileDownloadUri;
        } catch (IOException ex) {
            throw new RuntimeException("파일 저장 중 오류 발생: " + ex.getMessage());
        }
    }
}

저번 테스트 작성과 다른 점은 메뉴에 이미지 추가를 했다는 점이다. 이미지 추가를 하기 위해 MockMultipartFile을 이용하였다. 하면서 어려웠던 점은 원래는 uploadImageAndGetUrl을 통해서 이미지를 로컬에 저장하고 HTTP 요청(?)을 통해 URL 주소를 받아야 하는데 테스트 환경에서는 실제 HTTP 요청이 없기 때문에 테스트를 하면서 계속 에러가 났었다. 나중에 알고나서 어쩔 수 없이 테스트할 때는 우선 간단한 String으로 반환받기로 하였다.

profile
안녕하세요

0개의 댓글