2022/02/13 한 번에 끝내는 Spring 완.전.판 초격차 패키지 Online

김석진·2022년 2월 13일
0

Controller 테스트 작성

@WebMvcTest

Mockito랑 유사
Controller쪽 관련된 빈만 올리고, 컨트롤러도 우리가 원하는 Controller만 올려서 테스트 할 수 있다. 기본적인 Controller에 접근할 수 있는 경로들을 따라서 자동으로 추가해주기 때문에 Controller 테스트를 하기 좋다.

@WebMvcTest(DMakerController.class)
class DMakerControllerTest {

    @Autowired
    private MockMvc mockMvc;

    //DMakerController는 DMakerService를 의존하고있기떄문에
    //가짜 Bean을 등록해준다.
    @MockBean
    private DMarkerService dMarkerService;

    protected MediaType contentType =
            new MediaType(MediaType.APPLICATION_JSON.getType(),
                    MediaType.APPLICATION_JSON.getSubtype(),
                    StandardCharsets.UTF_8);

    @Test
    void getAllDevelopers() throws Exception {
        DeveloperDto juniorDeveloperDto = DeveloperDto.builder()
                .developerSkillType(DeveloperSkillType.BACK_END)
                .developerLevel(DeveloperLevel.JUNIOR)
                .memberId("memberId1")
                .build();

        DeveloperDto seniorDeveloperDto = DeveloperDto.builder()
                .developerSkillType(DeveloperSkillType.FRONT_END)
                .developerLevel(DeveloperLevel.SENIOR)
                .memberId("memberId2")
                .build();
        //-Mocking
        given(dMarkerService.getAllEmployedDevelopers())
                .willReturn(Arrays.asList(juniorDeveloperDto, seniorDeveloperDto));

        //mockMvc가 get으로 /developers를 호출
        mockMvc.perform(get("/developers").contentType(contentType))
                .andExpect(status().isOk())
                .andDo(print())
                .andExpect(
                        jsonPath("$.[0].developerSkillType", is(DeveloperSkillType.BACK_END.name()))
                ).andExpect(
                        jsonPath("$.[0].developerLevel", is(DeveloperLevel.JUNIOR.name()))
                ).andExpect(
                        jsonPath("$.[1].developerSkillType", is(DeveloperSkillType.FRONT_END.name()))

                ).andExpect(
                        jsonPath("$.[1].developerLevel", is(DeveloperLevel.SENIOR.name()))
                );

    }
}

요청과 응답에 대한 테스트를 진행할 수있었다.

Service Test

전에 작성한 Service Test에서 createDeveloper test를 진행
CreateDeveloper메소드를 테스트 해야하는것
1. validateCreateDeveloperRequest메소드(검증)이 제대로 동작하는지
2. 우리가 만든 레포지토리에 제대로 저장이 되는지

Mockito에서는 Mock 객체가 동작을 할 때 파라미터로 받은 값을 캡쳐해서 캡쳐한 값을 검증에 활용 할 수있다. -> ArgumentCapter가 필요하다

 //-create developer Test
    @Test
    void createDeveloperTest_success(){
        //given
        CreateDeveloper.Request request= CreateDeveloper.Request.builder()
                .developerLevel(SENIOR)
                .developerSkillType(FRONT_END)
                .experienceYears(12)
                .memberId("memberId")
                .name("name")
                .age(32)
                .build();

        given(developerRepository.findByMemberId(anyString()))
                .willReturn(Optional.empty());

        ArgumentCaptor<Developer> captor=
                ArgumentCaptor.forClass(Developer.class);   //캡터를 생성

        //when
        CreateDeveloper.Response developer = dMarkerService.createDeveloper(request);

        //then
        verify(developerRepository,times(1))
                .save(captor.capture()); //-특정 목이 몇번 호출됐는지 검증해줌

        Developer savedDeveloper=captor.getValue();
        assertEquals(SENIOR,savedDeveloper.getDeveloperLevel());
        assertEquals(FRONT_END,savedDeveloper.getDeveloperSkillType());
        assertEquals(12,savedDeveloper.getExperienceYears());
    }

이런식으로 create하는 로직이 있을경우 ArfgumentCaptor를 통해 실제저장된 데이터를 캡쳐링 해서 확인해 볼 수 있다.

리팩토링

사실 SI에서는 리팩토링이라는 개념이 거의 없다.

  • 왜냐하면 SI(System Integration) ->SM(System Maintenance)로 넘기고 끝인 경우가 많았기 때문
  • 일부 프레임워크를 만드는 팀은 제외

IT서비스에서는 리팩토링이 아주 중요해진 이유는?

  • 서비스 오픈 후 변화의 폭이 크다
    • 절대 바뀌지 않는다는 정책이 바뀜
      • 국내전용 -> 글로벌
      • PC전용 -> 모바일, 앱도 지원
    • 중간에 추가적인 레이어가 하나씩 더 들어가는 경우 흔함
    • 기존 구조를 뒤흔드는 기능 추가를 하는 경우가 많음
  • 1번의 큰 변화는 프로젝트를 최소 1.5배 이상 복잡하게 만듬
    이 복잡성을 줄여주는 것이 바로 리팩토링이다.

리팩토링의 주요 포인트

  • 일정에 맞추느라 품질이 다소 떨어졌던 부분
  • 서비스에 핵심적이면서 사용자 경험에 큰 영향을 끼치는 부분
  • 복잡도가 높고 향후 기능 추가, 변경 가능성이 높은 부분
  • 타 서비스에서도 활용할만한 공통적인 기능
    • 외부 라이브러리나 시스템으로 도출
  • 테스트코드 등도 가능
  • 도전적인 부분
    • 새로운 기술로 성능 향상이나 유지보수성 향상이 가능한 부분
    • 더 좋은 구성 방법이 생각나는 부분
profile
주니어 개발자 되고싶어요

0개의 댓글