반응형

2021/02/17 - [Development/Java] - Spring Boot Test Case 작성에 대한 생각 - Service Test

2021/02/17 - [Development/Java] - Spring Boot Test Case 작성에 대한 생각 - Repository Test

Repository, Service 에 대한 테스트를 살펴봤으니 이제 Controller 테스트를 확인해보자. Controller Test 에는 @WebMvcTest 를 사용했다. Controller 는 확인해야 할 부분이 다음과 같다. 

1. request 를 요청한 url 과 파라메터가 정확한지 여부.
2. 정상 처리 되었을데 요구한 응답을 보내주는지.
3. 비정상일때에 response 에 상태 코드가 정확히 전달 되는지. 

@RunWith(SpringRunner.class)
@WebMvcTest(UserRestController.class)
public class UserRestControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    public void getUsers() throws Exception {

        when(userService.findAll())
                .thenReturn(Arrays.asList(
                        Users.builder()
                                .email("test@test.com")
                                .name("test")
                                .status(UserStatus.APPLIED)
                                .build()
                ));

        this.mockMvc.perform(get("/users"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("@[0].email").value("test@test.com"));

    }
}

테스트케이스를 통해서 response 로 받는 내용과 상태 코드, 그리고 body 에 있는 내용들을 확인 해 볼 수 있다. 

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = [{"email":"test@test.com","name":"test","userStatus":"APPLIED"}]
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

그리고 print() 를 했기 때문에 콘솔 창에 위와 같은 결과도 같이 확인 해 볼 수 있다. 

그리고 잘못된 결과값이 나올 경우에도 response 가 잘 리턴 되는지 확인해 봐야 한다.

@Test
public void getUserNotFoundException() throws Exception {

  when(userService.findUserById("test11@test.com"))
    .thenThrow(
      new RuntimeException("User not found")
  );

  this.mockMvc.perform(get("/users/test11@test.com"))
    .andDo(print())
    .andExpect(status().isBadRequest());
}


위 테스트는 파라메터로 "test11@test.com" 을 보냈으나 사용자가 존재하지 않을때 400 error 와 메세지를 보내는 경우이다. 

MockHttpServletResponse:
           Status = 400
    Error message = null
          Headers = [Content-Type:"text/plain;charset=UTF-8", Content-Length:"14"]
     Content type = text/plain;charset=UTF-8
             Body = User not found
    Forwarded URL = null
   Redirected URL = null

결과로 400 에러가 전달 되며 Body 에는 메세지가 써있다. 

Controller 테스트에서는 고려해야 할 것들이 많은것 같다. request 를 받고 response 를 보내야 하는 곳이기 때문에 파라메터에 대한 검증과 상태코드, response 값과 message 들이 잘 구성되어있어야 한다. Status 코드가 200이 떨어졌을때 보다는 200이 아닌경우의 상황을 더 많이 고려해야 되지 않을까 생각이 된다. 

주의사항) 제 생각을 기준으로 작성하고 만든 소스코드이고 의견이기 때문에 틀린 부분이 있을수 있습니다.

728x90
반응형
반응형

Controller

개념

Pod 를 관리하는 역학을 한다.

Replicatoin Controller(레플리케이션 컨트롤러), ReplicaSet(레플리카 셋)

Replication Contller

  • 초기부터 있었던 기본적인 컨트롤러
  • 명시한 Pod 개수만큼 유지하도록 해준다.
  • 현재는 ReplcaSet 을 쓴다.

ReplicaSet

  • 레플리케이션 컨트롤러의 발전형.

  • 레플리케이션 컬트롤러와 차이점은 집합기반 셀렉터를 지원 한다. (in, notin, exists)

  • rolling-update 옵션 사용불가

  • 설정

    apiVersion: v1
    kind: ReplicaSet
    metadata:
      name: nginx-replicaset
    spec:
      template:
        metadata:
          name: nginx-replicaset
          labels:
            app: nginx-replicaset
        spec:
          containers:
          - name: nginx-replicaset
            image: nginx
            ports:
            - containePort: 80
      replicas: 3
      selector: 
        matchLabels: 
          app: nginx-replicase
    • .spec.template.metadata.labels 의 설정과 spec.selector.matchLabels의 설정이 같아야 한다.
    • selector 설정이 없을 경우 .spec.template.metadata.labels 를 따라간다.
  • 레플리카셋 삭제시 --cascade=false 옵션을 하면 레플리카셋만 삭제 가능하다. (Pod 삭제안됨)

Deployment(디플로이먼트)

  • Stateless 앱 배포시 사용하는 기본적인 컨트롤러

  • 레플리카셋을 관리한다.

  • 설정

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx-deployment
      template:
        metadata:
          name: nginx-deployment
          labels:
            app: nginx-deployment
        spec:
          containers:
          - name: nginx-deployment
            image: nginx
            ports:
            - containerPort: 80
  • 생성시 Deployemnt, ReplicaSet, Pod 가 생성된다.

  • 설정정보 Update 방법

    • kubectl set
    • kubectl edit
    • yaml 파일 수정후 apply
  • revsion

    • kubectl rollout history deployment 이름
    • kubectl rollout undo deploy (이전 revision 으로 롤백)
    • kubectl rollout undo deploy 이름 --to-revision=숫자 (특정 revision 으로 롤백)
  • Pod 개수 조정

    • kubectl scale deploy 이름 --replicas=숫자
  • 배포 정지, 재개, 재시작

    • kubectl rollout pause deployment/이름
    • kubectl rollout resume deployment/이름

Daemonset (데몬셋)

  • 클러스터 전체 노드에 특정 파드를 실행할 때 사용하는 컨트롤러

  • 클러스터 전체에 항상 실행시켜두어야 하는 파드에 사용

  • 설정

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: fluentd-elasticsearch
      namespace: kube-system
      labels:
        k8s-app: fluentd-logging
    spec:
      selector:
        matchLabels:
          name: fluentd-elasticsearch
      updateStrategy:
        type: RollingUpdate
      template:
        metadata: 
          labels:
            name: fluentd-elasticsearch
        spec:
          containers:
          - name: fluentd-elasticsearch
            image: fluent/fluentd-kubernetes-daemonset:elasticsearch
            env:
            - name: testenv
              value: value
            resources:
              limits:
                memory: 200Mi
              requests:
                cpu: 100m
                memory: 200Mi
    • .spec.updateStrategy.type : 다음 두가지중 선택
      • OnDelete : 파드가 삭제되었을때 반영된다.
      • RollingUpdate : 기본값 (1.5 이하에서는 OnDelete 가 기본값)
        • 템플릿 변경시 바로 반영
        • 모든 파드가 한꺼번에 반영되는건 아니고 .spec.updateStrategy.rollingUpdate.maxUnavailable 필드와 .spec.minReadySeconds 필드를 추가로 설정해 한번에 교체하는 파드를 조정한다.

StatefulSets (스테이트풀 셋)

  • 상태가 있는 파드들을 관리하는 컨트롤러
  • 생성될때 Pod 에 UUID 가 붙는게 아니라 숫자(0,1,2..)가 붙는다.
  • 삭제될때에는 숫자가 큰것부터 삭제가 된다. (업데이트시에는 Pod를 삭제하고 다시 생성하기 때문에 마찬가지로 숫자가 큰것부터 수정된다.)

Job (잡)

  • 실행된후 종료해야 하는 성격의 작업을 실행할때 사용하는 컨트롤러

  • 설정

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: pi
    spec:
      template:
        spec:
          containers:
          - name: pi
            image: perl
            command: []
          restartPolicy: Naver
      backoffLimit: 4
    • .spec.completions : 정상적으로 실행 종료 되어야 하는 파드 개수
    • .spec.parallelism : 동시에 실행 가능한 파드 개수
    • .spec.restartPolicy : 재시작 정책을 설정한다.

크론잡

  • job 을 시간 기준으로 관리한다. 주기적으로 반복이 가능하다.

  • 설정

    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      name: hello
    spec:
      schedule: "*/1 * * * *"
      jobTemplate:
        spec:
          template:
            spec:
                containers:
                - name: hello
                  image: busybox
                  args:
                  - /bin/sh
                  - -c
                  - date; echo Hello form the k8s
                restartPolicy: OnFailure
    • .spec.schedule : cron 명령 설정과 동일 (위는 1분)

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

1. 속성 정의 XML 파일에 추가되어야 하는 정의 

 xmlns:context="http://www.springframework.org/schema/context“
                                  http://www.springframework.org/schema/context
                                  http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
                <context:annotation-config/>       
Spring Container가 Annotation을 인식하기 위해서는 Spring Container에 BeanPostProcessor들이 등록되어있어야한다. <context:annotation-config/>을 추가하면 내부적으로 자동 등록된다.

2. Stereotype
- @Service : Business Layer를 구성하는 서비스 클래스 대상
- @Repository : Data Access Layer를 구성하는 클래스 대상
- @Controller : 프레젠테이션 Layer를 구성하는 클래스 대상, Spring MVC 기반의 경우에 한하여 사용

3. Dependencies
- @Inject, @Autowired, @Resource : 특정 Bean의 비지니스 기능 수행을 위해 다른 Bean을 참조할경우 사용
- @Inject (javax.inject-xxx.jar)
  멤버변수, setter 메소드, 생성자, 일반 메소드에 정의
- @Autowired : Framework에 종속적
- @Resource (jsr250-api.jar)
  멤버변수와 setter 메솓에 정의할수 있음

@Inject 

 @Autowired

@Resource 

type-driven injection 방식  type-driven injection 방식  

name-matching injection 방식  

JSR-330표준, Framework에 종속되지 않음 

 Spring Framework에 종속적   JSR-2500표준, Framework에 종속되지 않음
 @Named 이용하여 특정 빈 지정

@Qualifier를 이용하여 특정 빈 지정 

 Annotation 내에 name 속성을 통해 특정 빈 지정

 멤버변수, setter메소드, 생성자, 일반메소드

   멤버변수, setter메소드, 생성자, 일반메소드    멤버변수, setter메소드

 @Inject 사용을 권장


4. Auto-Detection
- <context:component-scan> 정의 필요
- 클래스패스 상에 존재하는 클래스들을 스캔하여 Stereotype Annotation이 정의된 클래스들과 필터와 비교하여 매칭되는 클래스들을 Bean으로 인식하여 자동으로 등록

 <context:component-scan base-package="패키지명" />

5. TestCase
- @RunWith : SpringFramework에서 Junit4.5+와의 연계를 위해 제공하는 SpringJUnit4ClassRunner클래스로 정의
- @ContextConfiguration : ApplicationContext 생성시 필요한 속성정의 파일 위치 명시


728x90
반응형

'Development > Java' 카테고리의 다른 글

객체에는 메서드가 포함되지 않는다?  (0) 2013.02.12
파일 입출력.  (0) 2013.01.29
[Spring]SpEL(Spring Expression Language)  (0) 2012.07.31
[Spring]Autowiring  (0) 2012.05.03
[Spring]AOP 주요 구성요소  (0) 2012.04.13

+ Recent posts