백엔드 웹개발 (Java/Spring) 초격차 - 1

김재현·2022년 9월 23일
0

FastCampus

목록 보기
1/9

강의 소개

나만의 MVC 프레임워크 만들기

목표

  • 객체지향 프로그래밍에 대한 이해
  • HTTP 프로토콜 및 HTTP 웹 서버 동작원리 이해
  • MVC 구조 및 DI 내부 동작 원리 이해

내용

  1. 개발환경 구축
  2. 객체지향 패러다임
  3. 웹 애플리케이션 이해
  4. 서블릿 프로그래밍
  5. JDBC 프로그래밍
  6. MVC 프레임워크 만들기
  7. DI 프레임워크 만들기
  8. Spring Boot 코드 분석

개발환경 구축

JDK 설치하기.

  • adoptium.net/ > Documentation > Install Eclipse Temurin

  • 맞는 OS를 골라 설치한다.

Apache Tomcat 설치

  • Servlet Interface(Spec) 구현체
    ServletContainer 중 하나
  • Which version? 에서는 아파치 톰캣 버전 별로 어떤 스펙을 구현했는지 확인 가능하다. 지원하는 자바 버전도 확인 가능.
  • 아파치 버전 9를 다운받는다.

  • 윈도우는 .zip 맥은 tar.gz를 다운받는다.
    압축파일을 열고, bin > startup.bat을 실행하면 아파치가 잘 설치되었음을 알 수 있다.
    (맥의 경우 startup.sh)
  • localhost:8080을 웹페이지에 입력해서 톰캣 페이지를 띄우는 것으로 제대로 실행됐음을 알 수 있다.

  • 종료는 bin > shutdown.bat을 실행하면 된다.

도커

  • 컨테이너 기반의 가상화 플랫폼
  • 컨테이너 기반의 가상화
    • 격리된 환경에서 프로세스를 실행하는 기술.
    • 애플리케이션은 도커 엔진을 통해 호스트 자원을 사용할 수 있고, 게스트OS가 없기 때문에 용량도 가볍운 편.

  • 하이퍼 바이저 기반의 가상화
    • Guest OS : 가상서버
      Host Operating System : 물리 서버.
      Hypervisor : 호스트와 게스트를 연결. 서버 가상화 기술로 호스트 서버에 설치되고 호스트와 게스트를 분리하며, 각각의 게스트는 하이퍼바이저에 의해 관리되고, 리소스를 할당받게 된다.
    • 격리된 환경에서 또 하나의 가상서버를 실행하는 기술
    • 게스트 OS는 다양한 OS 선택이 가능하다.
      게스트 OS에서 사용되는 애플리케이션은 호스트 서버의 자원을 사용하기 위해서는 게스트 OS를 통해야되고, 때문에 속도 측면에서 느릴 수 있다.

  • 도커 허브
    • 도커에서 제공하는 이미지 저장소
  • 도커 컴포즈
    • 다중 컨테이너를 정의하고 실행하기 위한 도구
    • YAML 파일을 사용하여 다중 컨테이너를 구성.

도커를 이용한 환경 구성

  • 도커 다운로드
    cmd에 docker -v를 입력하면 도커가 잘 깔렸는지 확인할 수 있음.
  • Docker Hub
    도커 이미지 저장소

  • mysql을 다운받아보자

  • Tags 탭을 눌러 좀 더 간단하게 할 수 있다.
    하지만 나의 경우
    error during connect: This error may indicate that the docker daemon is not running.
    라는 오류메시지가 출력되며 실패했다. 원인을 찾아보자.
  • 블로그를 좀 뒤져보니 해결방법이 나왔다.

  • 설정에 들어가서 저것을 체크해주는 것으로 문제 해결!

  • 이렇게 이미지를 다운받아보았다.

도커 컨테이너 생성 및 실행

  • 명령어
docker run --name ( name ) -e MYSQL_ROOT_PASSWORD=<password> -p3306:3306 -d mysql:{version}

docker run : 도커 실행
--name ( name ) : 이름 설정 
-e MYSQL_ROOT_PASSWORD=~~ : 패스워드 설정
-p 3306:3306 포트 설정
mysql:{version} : mysql 이미지 설정
  • 현재 실행중인 도커 컨테이너 목록 출력
    docker ps -a
  • MySQL 도커 컨테이너 접속
    • docker exec -it ( 컨테이너 이름 ) bash

  • MySQL 접속
    • mysql -u root -p
    • -u: username
      -p : password

  • mysql 접속.

객체지향 패러다임

1. 테스트 코드 실습

테스트코드 작성 이유

  1. 문서화 역할 : 잘 작성된 테스트코드는 그 자체로 문서화역할을 수행함.
  2. 코드에 결함을 발견하기 위해서 : 테스트코드를 작성하면서 결함을 발견할 수 있음.
  3. 리팩토링 시 안정성 확보
  4. 테스트 하기 쉬운 코드를 작성하다 보면 더 낮은 결합도를 가진 설계를 얻을 수 있음

TDD

  • Test Driven Development (테스트 주도 개발)
    • TFD (Test First Development) 라고도 함.
  • 프로덕션 코드보다 테스트 코드를 먼저 작성하는 개발 방법
  • TFD(Test First Development) + 리팩토링
  • 기능 동작을 검증(메서드 단위)

BDD

  • Behavior Driven Development (행위 주도 개발)
  • 시나리오 기반으로 테스트 코드를 작성하는 개발 방법
  • 하나의 시나리오는 Given, When, Then 구조를 갖는다.

비밀 번호 유효성 검증기

  • 요구사항
    • 비밀번호는 8~12자
    • 8자 보다 적거나 12자 보다 만으면 Exception 예외를 발생시킴.
    • 경계조건에 대해 테스트코드를 작성해야 함.

작업 준비하기

  • IntelliJ를 실행해서 새로운 프로젝트 생성.
  • AssertJ 디펜던시 추가.
    • 외부 라이브러리에서 확인할 수 있다.

  • 프로그램을 위한 소스코드 작성부분은 프로덕션 코드
    테스트 패키지 밑을 테스트 코드라고 부름.
    두 패키지를 맞춰주는 것이 좋다.

테스트 메서드 작성

  • alt + insert를 누르고 선택하는 것으로 테스트 메서드 삽입 가능

  • 요구사항을 주석처리해서 클래스에 명시한다.
    @DispalyName을 사용해서 목적이 무엇인지 명시해주자.
    메서드이름도 그럴듯하게 바꿔준다.
  • PasswordValidator라는 클래스에게 validate를 맡길 것임. 비밀번호 serverwizard에 대해.
    assertThatCode사용. 람다 표현식도 사용.
    • assertThatCode()안의 코드가 호출이 되었을 때 예외가 발생하지 않으면
      .doesNotThrowAnyException 반환. → 테스트가 성공한 것.
      물론, PasswordValidator 클래스가 없기에 당연히 실패한다.

  • 클래스를 생성해준다.

  • 그럼 바로 성공한다.

리팩토링 하기

  • 비효율적으로 작성된 코드.
  • password.length()라는 변수가 두변 중복되니 지역변수로 빼고 싶다.
    컨트롤 + 알트 + v

  • 리팩토링 후 테스트가 똑같이 통과된다면, 리팩토링이 잘 됐다고 생각할 수 있다.
    테스트 코드를 작성해두면 리팩토링 시 (심리적) 안정감을 확보할 수 있다.

  • Exception 발생한 경우에 대해서도 Test 코드 작성

경계 조건에 대한 테스트

  • 경계값에서 오류가 발생하는 경우가 많다.
    때문에 경계값에 대해 테스트를 생성해서 오류를 방지하는 것이 좋다.
    @ParameterizedTest가 필요하다.
  • build.gradle에서 junit-jupiter-params 디펜던시를 추가해준다.

  • @ValueSource를 주입해주면 validatePasswordTest2가 받을 수 있다.

테스트코드를 작성하다보면 결합도가 낮아진다.

  • Passay 의존성을 추가해준다.
    implementation 'org.passay:passay:1.6.1'

Parameterized Test가 뭔데?

  • 테스트 코드를 작성할 때 중복되게 작성해야할 때 사용할 수 있음.
    중복되는 부분은 여러 개의 테스트 메서드를 만드는 것은 관리도, 가독성에도 좋지 못함.

사용방법

  1. 의존성 추가.
  2. @ParameterizedTest 사용
    • 1) @ValueSource
      • @ValueSource는 리터럴 값의 단일 배열을 지정할 수 있으며 매개 변수화 된 테스트 호출마다 단일 인수를 제공하는데만 사용 가능하다.
      • short, byte, int, long, float, double, char, boolean 유형의 리텉럴 값 지원.
      • @ValueSource안에 원하는 타입을 적어준 뒤 리터럴 값을 넣어주면 된다.
    • 2) Null and Empty Sources
      • @NullSource @EmptySource를 사용하면 파라미터 값으로 null과 empty를 넣어준다.
    • 3) @EnumSource
      • enum 도 지원한다.
    • 4) @MethodSource
      • 보다 복잡한 인수를 제공하는 방법으로 @MethodSource를 사용한다.
  • 예시 코드
@ParameterizedTest(name = "{index}: {3}")
@MethodSource("invalidParameters")
@DisplayName("User 생성 유효성 검사")
void invalidCreate(String name, String email, String password, String message, String exceptionMessage) {
    IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> new User(email, name, password));
    assertThat(e.getMessage()).isEqualTo(exceptionMessage);
}

static Stream<Arguments> invalidParameters() throws Throwable {
	return Stream.of(
    	Arguments.of("a", VALID_EMAIL, VALID_PASSWORD, "name 2자 미만", NAME_NOT_MATCH_MESSAGE),
        Arguments.of("qwertasdfzpl", VALID_EMAIL, VALID_PASSWORD, "name 10자 초과", NAME_NOT_MATCH_MESSAGE),
        Arguments.of("1232ad", VALID_EMAIL, VALID_PASSWORD, "name 숫자 포함", NAME_NOT_MATCH_MESSAGE),
        Arguments.of(VALID_NAME, VALID_EMAIL, "Passw0rd", "password 특수문자 제외", PASSWORD_NOT_MATCH_MESSAGE),
        Arguments.of(VALID_NAME, VALID_EMAIL, "P@ssword", "password 숫자 제외", PASSWORD_NOT_MATCH_MESSAGE),
        Arguments.of(VALID_NAME, VALID_EMAIL, "p@ssw0rd", "password 대문자 제외", PASSWORD_NOT_MATCH_MESSAGE),
        Arguments.of(VALID_NAME, VALID_EMAIL, "P@SSW0RD", "password 소문자 제외", PASSWORD_NOT_MATCH_MESSAGE),
        Arguments.of(VALID_NAME, "asdfasd", VALID_PASSWORD, "email 양식 틀림", EMAIL_NOT_MATCH_MESSAGE)
    );
}

0개의 댓글