단위테스트 AAA

AAA는 Arrange(준비), Act(실행), Assert(단언)의 약자로 클린 코드와 가독성을 유지하는 방향으로 테스트를 구조화하는 접근법을 의미한다. 오늘날 AAA는 업계 전반에 걸쳐 거의 표준이 된 테스트 패턴이다.

@Test

public void givenStreamWhenSumThenEquals6(){
  //Arrange(준비)
  Stream theStream = Stream.of(1, 2, 3);
  //Act(실행)
  int sum = theStream.mapToInt(i -> i).sum();
  //Asseert(단언)
  assertEquals(6, sum);
}

public void givenStreamWhenSumThenEquals6(): 테스트 메소드의 이름입니다. 이 메소드는 스트림의 합이 6과 같을 때 테스트를 통과한다.

//Arrange(준비): 테스트의 준비 단계를 표시한다. 이 단계에서는 테스트에 필요한 데이터를 설정한다.

Stream<Integer> theStream = Stream.of(1, 2, 3);: 스트림을 생성하고 1, 2, 3 세 개의 정수를 포함시킨다.

//Act(실행): 테스트의 실행 단계를 표시한다. 이 단계에서는 실제 작업을 수행하고 결과를 얻는다.

int sum = theStream.mapToInt(i -> i).sum();: 스트림의 모든 정수를 int로 변환하고(sum) 합계를 구한다. 결과는 변수 sum에 저장된다.

theStream.mapToInt(i -> i) : 이 부분에서 람다 함수 i -> i를 사용하여 스트림의 각 요소(Integer 객체)를 int 기본 타입으로 변환한다. 그 결과 IntStream이 생성된다.sum() : 이 부분에서 IntStream의 sum() 메소드를 호출하여 스트림에 있는 모든 정수의 합을 계산한다 . 여기서는 1 + 2 + 3 = 6을 계산하게 된다.

//Assert(단언): 테스트의 단언 단계를 표시한다. 이 단계에서는 결과가 기대한 값과 일치하는지 확인한다.

//assertEquals(6, sum);: sum 변수의 값이 6과 같은지 확인합니다. 값이 같으면 테스트가 통과되고, 그렇지 않으면 테스트가 실패한다.

Thymeleaf를 이용하여 웹 어플리케이션을 개발할 때, 유효성 검사 및 에러 처리는 매우 중요한 부분이다. 

이번 블로그 포스트에서는 Thymeleaf에서 사용자 정의 속성을 이용한 에러 처리 방법에 대해 설명하겠다.

 

<style>

.field-error {

font-size:0.8em

}

</style>

<span class="field-error" th="error">

//글로벌오류

//총액 (상품수량*단가)1000만원 초과 금지

if(SaveForm.getQuantity()* saveForm.getPrice() > 100000L ) {

bindingResult.reject(errorcode"",errorArgs null, defalutMessage"총액(상품수량x단가) 10만원 초과 안됩니다")

return "product/saveForm"

}//상품 정보 저장 폼에서 총액이 1,000만 원을 초과하는 경우 에러 발생시키는 코드다.




if(saveForm.getQuantity()= 100) {

bindingResult.reject("quantity",null,"총액 초과~안됩니다")}
//위는 html에 반영 안되고 있는 것.

//HTML에 에러 메시지 반영하기(Input 창 옆)
SaveForm.html

<div th:if "${#fields.hasGlobalErrors()} ">

<p class="field-error" th:each="${#fields.globalErrors()" th:text="${err}> </p>
// 다음과 같이 Thymeleaf의 th:if와 th:each 속성을 이용하여 전역 에러 메시지를 출력할 수 있다.
</div>

에러 처리 로직이 복잡해지면 하드코딩된 에러 코드를 별도의 파일에 정리하고, 소스 코드에서는 에러 코드만 참조하는 것이 좋다. 이렇게 하면 에러 코드가 변경되더라도 소스 코드를 수정할 필요가 없으며, 외부 파일에서만 수정하면 되기 때문이다.

결론적으로, Thymeleaf에서 사용자 정의 속성을 이용한 에러 처리를 통해 유효성 검사 및 에러 메시지 출력을 간편하게 할 수 있다. 이 방법을 사용하면 코드의 가독성과 유지보수가 편해진다.

웹 애플리케이션에서 "데이터 검증"은 사용자가 입력한 정보가 올바르고, 예상대로 작동하게 하기 위해 필수적이다.사용자에게 안내 메시지를 제공하여 오류를 수정할 수 있도록 해야 한다. 메시지는 입력창 아래에 표시할 수 있다.


데이터 검증 방법
①.테이블의 정의에 따른 검증: 데이터 타입, 길이 등을 확인하여 오류를 Catch 할 수 있다.
②.서버에서의 검증: "컨트롤러"에서 요청 데이터를 검증한 후, 서비스로 데이터를 전달하는 방법도 존재.
③.클라이언트에서의 검증: "자바스크립트 로직"을 사용하여 서버 리소스를 사용하지 않고 검증을 수행한다.

 

검증 케이스
①.데이터 타입 및 크기 검증
②.두 개의 필드 값 비교 (예: 비밀번호 확인)
③.권한에 따른 데이터 검증 (예: 회원 등급에 따른 할인율 적용)
④.비즈니스 룰에 따른 검증 (예: 상품 가격과 수량의 곱이 특정 금액을 초과하지 않도록 함)



검증 방법에 대한 예:
①.DB: 제약조건, 데이터 타입, 크기 등을 확인한다.
②.서버: 컨트롤러에서 요청 데이터를 검증하고, 서비스로 전달한다.
③.클라이언트: 자바스크립트를 사용하여 검증 로직을 실행한다.
④.검증 주석: @Valid와 같은 주석을 사용하여 검증을 적용할 수 있다.
검증 결과는 BindingResult에 저장되며, 오류가 있는 경우 해당 뷰를 다시 표시하도록 할 수 있다.

 

출처: FastCampus 한 번에 끝내는 Java/Spring 웹 개발 마스터 객체 지향 입문

03. 함수와 메서드


함수란(function)

1.하나의 기능을 수행하는 일련의 코드

2.구현된(정의된)함수는 호출하여 사용하고 호출된 함수는 기능이 끝나면 제어가 반환됨.

3.함수로 구현된 하나의 기능은 여러 곳에서 동일한 방식으로 호출되어 사용될 수 있다.

한 군데에서 기능을 구현하면 더한다라는 기능을 갖다 쓰면 된다.


함수 정의하기


함수는 이름, 매개 변수, 반환 값, 함수 몸체(body)로 구성된다.

int add(int num1, int num2) {
  int result;
  result = num1 + num2;
  return result;
}

반환이 없을 경우에는 void add() {

}이렇게 쓴다. 매개변수는 아무 것도 안써도 된다.


함수 구현하기 예제


public class FunctionTest {
  
  public static int addNum(int num1, int num2) {
    
    int result;
    result = num1 + num2;
    return result;
  }
  public static void sayHello(String greeting) {
    
    System.out.println(greeting);
  }
  
  public static int calcSum()
  {
    int sum = 0;
    int i;
    
    for(i = 0; i<=100; i++) {
      sum += i;
    }
return sum;
    
  }
  public static void main(String[] args) {
    
    int n1 = 10;
    int n2 = 20;
    
    int total = addNum(n1, n2);
    System.out.println(total);//30
    
    sayHello("안녕하세요");//안녕하세요
    
    total = calcSum();
    System.out.println(total);//5050
  }
}

함수 호출과 스택 메모리


스택: 함수가 호출될 때 지역 변수들이 사용하는 메모리

함수의 수행이 끝나면 자동으로 반환 되는 메모리

public class FunctionTest {
  
  public static int addNum(int num1, int num2) {
    
    int result;
    result = num1 + num2;
    return result;
  }
  public static void sayHello(String greeting) {
    
    System.out.println(greeting);
  }
  
  public static int calcSum()
  {
    int sum = 0;
    int i;
    
    for(i = 0; i<=100; i++) {
      sum += i;
    }
return sum;
    
  }
  public static void main(String[] args) {
    
    int n1 = 10;
    int n2 = 20;
    
    int total = addNum(n1, n2);
    System.out.println(total);//30
    
    sayHello("안녕하세요");//안녕하세요
    
    total = calcSum();
    System.out.println(total);//5050
  }
}

main 메서드에서 호출되지 않은 메서드들은 스택 메모리에 저장되지 않는다. 스택 메모리는 메서드 호출에 대한 스택 프레임만 저장하므로, 호출되지 않은 메서드는 스택 메모리에 저장되지 않는다. 호출되지 않은 메서드의 경우, 실행 시점에 스택 메모리에 영향을 주지 않는다.

이 코드에서 스택 메모리의 삭제가 발생하는 부분은 다음과 같다:

addNum 메서드가 호출되고 종료될 때 (return 값 반환)

sayHello 메서드가 호출되고 종료될 때 (메서드 실행 완료)

calcSum 메서드가 호출되고 종료될 때 (return 값 반환)

main 메서드가 종료될 때 (메서드 실행 완료)

따라서 예시에서 총 4번의 스택 프레임 삭제가 발생하며, 이는 스택 메모리에서 각 스택 프레임이 삭제되는 것을 의미한다.


메서드 (method)


1.객체의 기능을 구현하기 위해 클래스 내부에 구현되는 함수

2.C++에서는 멤버 함수(member function)이라고도 한다.

3.메서드를 구현함으로써 객체의 기능이 구현 된다.

4.메서드의 이름은 그 객체를 사용하는 객체(클라이언트)에 맞게 짓는 것이 좋다.

객체가 있으면 다른객체가 그 객체를 사용하는 경우가 있다.

사용 할 때 메서드를 호출 할 떄, 호출하는 입장에서 명령하는 것이 좋다.

getStudentName()

5.클래스안에 있고 클래스의 멤버 변수들을 활용해서 구현한다.

출처: FastCampus 한 번에 끝내는 Java/Spring 웹 개발 마스터 객체 지향 입문

 

생활 속에서 객체 찾아 클래스로 구현해 보기

객체를 찾아보자.

1.온라인 쇼핑몰에 회원 로그인을 하고 여러 판매자가 판매하고 있는 제품 중 하나를 골라 주문을 한다.

여기서는 온라인 쇼핑몰 자체는 System이 되고

회원,판매자,제품,주문이 객체에 해당 된다.


2.아침에 회사에 가는 길에 별다방 커피숍에 들려 아이스 카페라떼를 주문 했다.

여기서 객체는 나,회사,커피숍,커피,주문,알바


3.성적확인을 위해 학사 관리 시스템에 로그인 하여 수강 한 과목들의 성적을 확인 했다.

학생,과목,교수,강의실,통계,통계 방법 등 보이지 않는 것의 명사 또한 객체가 된다.

클래스는 객체의 청사진 이다.

객체의 속성은 클래스의 멤버 변수로 선언 한다.

//학생 클래스

Public class Student {
//속성,멤버 변수
 int studentNumber;
 String studentName;
 int majorCode;
 String majorName;
 int grade;
}
//주문 클래스
public class Order {
  int orderId;
  String buyerId;
  String sellerId;
  int productId;
  String orderData;
}
//회원 클래스
public class UserInfo {
  //소문자로부터 시작해서 대문자
  String userId;
  String userPassWord;
  String userName;
  String userAddress;
  int phoneNumber; 
}

절차 지향 프로그래밍의 대표적인 언어-> C언어

시간의 흐름에 따라 프로그래밍

일어난다->씻는다->밥을 먹는다->버스를 탄다->요금을 지불한다->학교 도착

객체 지향 프로그래밍 (Object Oriented Programming)

학교를 가는 과정엔

학생,버스,학교,밥이 있을 수 있다.

그 객체 사이의 관계가 있다. 학생이 버스를 탄다라고 했을 때,

학생이 버스를 타게 되면 돈을 내야되고

버스는 승객이 늘어나고 매출이 올라가는 등 관계가 있다.

그런 관계를 가지고 프로그래밍을 하는 것이 객체 지향 프로그래밍이다.

C++,C#,Python,Javascript가 속한다.

그렇다면 객체 지향 프로그램은 어떻게 구현하는가?

객체를 정의하고

각 객체 제공하는 기능들을 구현하고

각 객체가 제공하는 기능들 간의 소통(메세지 전달)을 통하여 객체간의 협력을 구현

 

 

 

출처: FastCampus 한 번에 끝내는 Java/Spring 웹 개발 마스터 객체 지향 입문

 

Spring boot는 스프링 기반으로 실무 환경에 사용 가능한 수준의 '독립실행형' Application을 복잡한 고민 없이, 빠르게 작성할 수 있게 도와주는 여러가지 도구의 모음이다.

스프링 ≠ 스프링부트 !

Spring Boot 핵심 목표

ⓐ 매우 빠르고 광범위한 영역의 스프링 개발 경험을 제공

ⓑ 강한 주장을 가지고, 즉시 적용 가능한 기술 조합을 제공하면서, 필요에 따라 원하는 방식으로 손쉽게 변형 가능

ⓒ Project에서 필요로 하는 다양한 비기능적인 기술(내장형 서버,보안,메트릭,상태 체크,외부 설정 방식 등) 제공

ⓓ코드 생성이나 XML 설정 필요하지 않음.

Repository 3 요구 사항

* 영상 출처: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/unit/49580

(00:46)

Controller : 사용자의 요청을 처리하고 적절한 Service를 호출하여 응답을 보냅니다.

Service : 실질적인 비즈니스 로직을 처리하고, Repository에 요청을 보냅니다.

Repository : 데이터베이스에서 데이터를 읽고 쓰는 역할을 합니다.

Domain : 비즈니스 로직에서 다루는 데이터 객체입니다. 예를 들어, 사용자 정보, 게시글, 상품 등이 있습니다.

(03:45)

MVC와 Template Engine

* 영상 출처: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/unit/49577

(06:22)

(06:31)

(06:45)

(07:05)

(08:05)

(08:08)

(08:26)

(08:44)

(10:29)

API

* 영상 출처: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/unit/49578?tab=curriculum

(01:12)

}
@GetMapping ("hello-string")
@ResponseBody
public String helloString (@Request Param("name") String name) {
return "hello " + name;
}

@ HTTP에도 head,body가 있는데 이 body에 직접 넣어주겠다. 라는 뜻.

(02:31)


(04:00)

(04:56)

(05:24)

(08:44)

 

+ Recent posts