'controller'에 해당되는 글 7건

IT 지식/ngrinder

ngrinder Mac os 간단 설치 및 테스트 방법

api의 성능 테스트를 위해서 네이버에서 만든 ngrinder 설치하고 테스트를 진행해봤다.


ngrinder는 controller와 agent로 구성이 되어 있는데 이에 대한 내용은 https://naver.github.io/ngrinder/ 해당 내용을 체크하자.


1. Controller 설치
- 톰캣을 설치하고 아래 주소에서 war를 다운받아서 실행시킨다.
https://github.com/naver/ngrinder/releases
단, 3.4.2는 테스트 스크립트 실행 시 unexpected token에러가 발생한다. 그래서 3.4.1을 사용하는걸 추천한다.

설치 완료되면 아래 url로 접근 해서 확인 (초기 계정은 admin/admin)
- 뒤에 root path는 편의를 위해서 war 파일을 ngrinder-controller-3.4.1.war => ngrinder.war로 변경해서 ngrinder로 사용

http://localhost:8080/ngrinder

 

2. Agent 설치
Agent는 테스트에서 필요한 worker process를 실행시켜주고 관리하는 역할을 한다.
- agent를 다운받고 내부에 ./run_agent.sh를 실행시킨다.

- 실행이 완료되면 Agent Management에 들어가면 정상적으로 동작하는걸 확인할 수 있다.

주의사항
먼저 자바 1.9이상의 버전에서는 Agent을 지원을 하지 않는다. 1.9에서 agent 실행 시 다음과 같은 오류가 난다.

1
java.lang.ClassCastException: class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader and java.net.URLClassLoader are in module java.base of loader 'bootstrap')
cs
이는 1.9에서 URLClassLoader를 사용하는 방식이 바뀌었으나 ngrinder agent가 아직 지원하지 못해서 발생하는 오류인거 같다. 1.8을 사용하면 괜찮다.



테스트 진행

각 옵션을 설정하고 테스트를 진행하면 아래와 같이 TPS결과가 나온다. 각 설정 옵션에 대해서는 인터넷이나 메인 git에 가면 자세히 나와있다.


Agent, VUser를 조절해가면서 api의 성능을 tps를 확인하면서 조절해서 테스트하면 된다.



'IT 지식 > ngrinder' 카테고리의 다른 글

ngrinder Mac os 간단 설치 및 테스트 방법  (0) 2019.03.11
web/Spring

생성한 Custom validation으로 에러메시지 출력하기

바로 직전 https://wedul.tistory.com/562?category=595982 에서 Custom validation을 만들어서 입력된 값에 validation을 체크하는 방법을 알아봤다.

그럼 이 validation체크를 통해서 front에 상황에 맞는 에러를 보내줄 수 있도록 조치를 취해보자.

우선 @valid 처리를 했었던 컨트롤러에서 에러 메시지를 수집해야한다. 


1. Controller

Spring에서 Validation 작업을 진행할 시 validation에 문제가 발생하면 에러 내용을 묶어서 BindingResult로 처리할 수 있도록 제공해준다. 이를 사용하기 위해서 parameter로 BindingResult값을 추가해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * 회원가입
 *
 * @param reqDto
 * @return
 * @throws Exception
 */
@RequestMapping("/join")
public ResponseEntity<?> join(@Valid UserDto reqDto, BindingResult bindingResult) throws Exception {
    // check constraint rules
    this.checkConstraintRule(bindingResult);
 
    return ResponseEntity.ok(userService.insertUser(reqDto));
}
cs


2. 에러 처리

BindingResult에 validation을 체크하고 발생한 에러들에 대한 내용을 하나씩 뽑아서 국제화 메시지로 변경해주고 \n으로 데이터를 묶어서 view에 전달할 수 있도록 데이터를 바꿔 준다. 공통적으로 사용하것이기 때문에 공통 Controller 클래스를 하나 만들어서 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.wedul.common.controller;
 
import com.wedul.common.error.BadRequestException;
import com.wedul.common.util.MessageBundleUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.validation.BindingResult;
 
import java.util.stream.Collectors;
 
/**
 * wedulpos
 *
 * @author wedul
 * @since 2018-12-24
 **/
@AllArgsConstructor
public class BaseController {
 
  private final MessageBundleUtil messageBundleUtil;
 
  protected void checkConstraintRule(BindingResult bindingResult) throws BadRequestException {
    String msg = null;
    if (bindingResult.hasErrors()) {
       msg = bindingResult.getFieldErrors()
              .stream()
              .map(error -> messageBundleUtil.getMessage(error.getDefaultMessage()))
              .collect(Collectors.joining("\n"));
    }
 
    if(StringUtils.isNotBlank(msg)) {
      throw new BadRequestException(msg);
    }
 
    return;
  }
 
}
 
cs


3. 에러 핸들링

나는 에러를 에러 코드와 메시지로 전달해주는 방식을 좋아한다. 사실 다른 정보를 다 전달해줘봐야 프론트에서 처리하기도 어렵고 나머지는 로그로써 확인하는게 더 편하다. 그래서 전달하는 값을 정제하기 위해서 @ControllerAdvice를 통해 출력되는 에러를 재정의 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.wedul.common.config;
 
import com.wedul.common.enums.EnumErrorType;
import com.wedul.common.error.BadRequestException;
import com.wedul.common.error.ForbiddenException;
import com.wedul.common.error.NotFoundException;
import com.wedul.common.error.InternalServerException;
import lombok.Builder;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
 
/**
 * 에러 유형을 나타내는 Config
 *
 * @author wedul
 * @Date 2017. 07. 09
 */
@ControllerAdvice
public class ExceptionConfig {
 
  @Data
  @Builder
  private static class ErrorResponse {
    private int errCode;
    private String msg;
  }
 
  @ExceptionHandler({Exception.class})
  @ResponseBody
  public ErrorResponse errorHandler(Exception ex) {
    if(ex instanceof BadRequestException) {
      return this.getError(400, ex);
    } else if(ex instanceof ForbiddenException) {
      return this.getError(403, ex);
    } else if(ex instanceof NotFoundException) {
      return this.getError(404, ex);
    } else if(ex instanceof InternalServerException) {
      return this.getError(500, ex);
    } else {
      return ErrorResponse.builder().errCode(500).msg(ex.getMessage()).build();
    }
  }
 
  /**
   * 기본 에러 내용 출력
   *
   * @param errorCode
   * @param ex
   * @return
   */
  private ErrorResponse getError(int errorCode, Exception ex) {
    String message = ex.getMessage();
    if(StringUtils.isBlank(message)) {
      message = EnumErrorType.getErrorMsg(errorCode);
    }
 
    return ErrorResponse.builder().errCode(errorCode).msg(message).build();
  }
 
  /**
   * Error code 만들기
   *
   * @return String
   * @date 2017. 7. 9.
   * @author wedul
   */
  private String makeErrorCode(Exception ex) {
    StackTraceElement[] ste = ex.getStackTrace();
    StringBuffer sb = new StringBuffer();
    StackTraceElement[] arrayOfStackTraceElement1;
    int j = (arrayOfStackTraceElement1 = ste).length;
    for (int i = 0; i < j; i++) {
      StackTraceElement el = arrayOfStackTraceElement1[i];
      String className = el.getClassName();
      if (className.startsWith("com.wedul.wedulpos")) {
        sb.append(className.substring(className.lastIndexOf("."+ 1).toUpperCase()).append("[");
        sb.append(el.getLineNumber()).append("]");
        break;
      }
    }
    if (StringUtils.isBlank(sb.toString())) {
      return ex.getStackTrace()[0].getClassName();
    }
    return sb.toString();
  }
}
 
cs


4. 테스트 진행

1) @NotBlank, @Email 확인


2) Custom Validation인 password check



소스코드 : https://github.com/weduls/wedulpos_boot

참고 : https://meetup.toast.com/posts/147

web/Spring

Custom Validation 만들어서 추가하기

Spring에서 @NotBlank, @Email등 여러 템플릿에 맞게 Validation을 넣을 수 있다.

하지만 추가적으로 패스워드 규칙과 같이 별도 체크할 validator가 필요할 때 만들어서 사용해야 하는데 만들어서 지정해보는 작업을 해보자.


1. Controller

요청을 받을 DTO앞에 @Valid 어노테이션을 추가해야한다.

1
2
3
4
5
6
7
8
9
10
11
/**
 * 회원가입
 *
 * @param reqDto
 * @return
 * @throws Exception
 */
@RequestMapping("/join")
public ResponseEntity<?> join(@Valid UserDto reqDto) throws Exception {
    return ResponseEntity.ok(userService.insertUser(reqDto));
}
cs


2. Annotation 추가

Validation 사용을 위해서 필드에 @NotNull, @NotBlank와 같이 어노테이션을 붙혀줘야한다. 그래서 Custom Validation을 만들고 필드에 붙히기 위해서 어노테이션을 만들어줘야한다. 기본적으로 표현되는 메시지는 설정을 진행한 messageSource에서 가져오는데 가져오지 못하면 default로 설정한 메시지를 출력하게 할 수있다. 그리고 기존에 어노테이션 만들던 방법과 조금 다른 부분이 있는데 바로 @Constraint 필드이다. 여기서 지정하는 설정은 어떤 검증 클래스를 사용해서 필드의 값을 검증할 건지 지정해준다. 이 방법을 위해서는 ConstraintValidator 인터페이스를 구현한 클래스를 지정해줘야한다. 아래에서 확인해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.wedul.common.annotation;
 
import com.wedul.common.validation.PasswordValidator;
 
import javax.validation.Constraint;
import java.lang.annotation.*;
 
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {PasswordValidator.class})
public @interface PasswordCheck {
 
  String message() default "";
Class<?>[] groups() default {};
 Class<? extends Payload>[] payload() default {};
cs
}
 
cs


3. Validator 추가

ConstraintValidator 인터페이스를 구현해주면서 지정해주는 제네릭 값 첫 번째에는 2번에서 만든 애노테이션 객체가 들어가고 두 번째 값에는 이 어노테이션 값이 붙어서 Constraint 작업을 진행할 필드의 데이터 유형을 넣는다. (패스워드라면 String) 만약 특정하기 어려운 어노테이션인경우 Object를 붙여서 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.wedul.common.validation;
 
import com.wedul.common.annotation.PasswordCheck;
import org.apache.commons.lang.StringUtils;
 
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
 
/**
 * 패스워드 validation
 *
 * @author wedul
 * @since 2018-12-23
 **/
public class PasswordValidator implements ConstraintValidator<PasswordCheck, String> {
 
  @Override
  public boolean isValid(String value, ConstraintValidatorContext context) {
    // 6자리이상 대문자 포함
    return StringUtils.isNotBlank(value) && value.length() >= 6 && value.chars().boxed().filter(data -> Character.isUpperCase(data)).findAny().isPresent();
  }
}
 
cs


4. DTO 적용

적용하고자하는 곳에 추가한 필드에 넣어보자!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package com.wedul.wedulpos.user.dto;
 
import com.wedul.common.annotation.PasswordCheck;
import com.wedul.common.dto.CommonDto;
import com.wedul.common.util.HashUtil;
import lombok.*;
import org.apache.ibatis.type.Alias;
 
import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
 
/**
 * User정보 Dto 
 * 
 * @author wedul
 * @date 2017. 11. 4.
 * @name UserDto
 */
@Alias("UserDto")
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Entity
@Table(name = "user")
public class UserDto extends CommonDto implements Serializable {
 
    @Id
    @GeneratedValue
    private int userId;
 
    @Column(nullable = false)
    private String nickname;
 
    @Column(nullable = false)
    @NotBlank(message = "user.login.message.mustemail")
    @Email(message = "user.login.message.validation_email")
    private String email;
 
    @Column(nullable = true)
    @PasswordCheck(message = "user.join.message.password")
    private String password = "";
 
    @Column(nullable = true)
    private String snsId;
 
    @Column(nullable = false)
    private boolean isAdmin = false;
    
    public UserDto(String email) {
        this.email = email;
    }
    
    public UserDto(String email, String password) {
        this.email = email;
        this.password = password;
    }
    
    public UserDto(String email, String password, boolean isAdmin) {
        this.email = email;
        this.password = password;
        this.isAdmin = isAdmin;
    }
    
    public UserDto(String email, String password, String nickname, boolean isAdmin) {
        this.email = email;
        this.password = password;
        this.nickname = nickname;
        this.isAdmin = isAdmin;
    }
    
    public String getEcPassword() {
        return HashUtil.sha256(this.password);
    }
 
}
 
cs


validation 오류 발생시 상황에 맞는 문구가 나올 수 있도록 별도의 설정을 해줘야 하는데 그 부분은 다음시간에 정리해서 올려보자.


우선 Custom Validation을 만든부분만 정리하자.


web/Spring

spring에서 List 또는 Array 데이터를 Controller에서 받기

컨트롤러에서 List<>데이터를 받아서 매핑하기 위해서 필요한과정을 정리해본다.



1. List<PersonDto> 데이터를 받기


먼저 controller에서 @RequestBody List<PersonDto>를 받도록 설정한다. 

그리고 ajax를 통해서 요청하는 부분에서 다음과 같이 진행한다.


 

1
2
3
4
5
6
7
let data = [{'name':'cjung', 'age':30}, {'name':'wedul', 'age':28}];
 
$.ajax({
    url:....,
    type:...,
    param: JSON.stringify(data);
});
cs






2. DTO객체 안에 LIST 변수에 데이터를 매핍 하고자 하는경우


기존에 습관대로 진행을 다음과 같이 먼저 해보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// javascript
let param = [{ name : 'wedul', age: 1}, {name:'dd', age:2}];
 
// UserDto
private String name;
private int age;
 
// UserDataList
public UserDataList {
 List<UserDto> userDatas;
 
}
 
 
// UserController
public Map<String, Object> getUsers(@ModelAttribute UserDataList users);
cs




Property referenced in indexed property path is neither an array nor a List nor a Map ...

다음과 같은 에러가 발생하고 

formData를 확인하면

param[0]["name"] = wedul
param[0]["age"]=1

과 같이 되어있는것을 확인할 수 있다.

이를 해결하기 위해서는 다음과  json 데이터를 만들어서 전송한다.



1
2
3
var param = {}; 
param['userDatas[' + index +'].name'] = 'yhkim' ;
param['userDatas[' + index +'].age'] = 1; 
cs


web/Junit

Junit 정리 - MockMvc를 이용한 컨트롤러 테스트

입사 후 개발을 한지 벌써 3년 차가 되었다. 
개발을 처음 접할 때는 어떻게 구현해야 할지 어떻게 만들어야 하는지에 대한 관심이 더 컸다. 

하지만 요새는 개발 후 어떻게 테스트를 진행하여 먼저 버그를 예방(?)할 수 있는지 고민하기 시작했다.

성격이 덜렁거리거나 대충 하는 스타일은 아니었는데, 요즘 열정이 많이 식어서 그런지 단순한 부분에서 버그를 유발하는 것 같아서 TDD를 통해 고쳐보려고 Junit을 공부하기로 했다.

스프링의 각 영역인 Controller. Service, Dao에 대한 테스트를 총 3장에 걸쳐서 설명하겠다.

그리고 Mockito에 대한 설명을 추가로 진행하겠다.

0. 공통

우선 스프링에서 단위테스트를 진행하기 위해서는 몇가지 라이브러리가 필요하다. 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>
<!-- mockito프레임워크 사용을 위한 라이브러리 -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.9.5</version>
    <scope>test</scope>
</dependency>
<!-- spring test는 MockMvc와 다른 테스트를 포함한다. -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>3.2.3.RELEASE</version>
    <scope>test</scope>
</dependency>
cs



1. Controller
Controller 단위 테스트를 진행하기 위해서 MockMvc를 활용할 수 있다.

MockMvc란?
-> 브라우저에서 요청과 응답을 의미하는 객체로서 Controller 테스테 사용을 용이하게 해주는 라이브러리이다.

먼저 테스트를 진행할 컨트롤러는 다음과 같다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.wedul.wedulpos.user.controller;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import com.wedul.wedulpos.user.dto.UserDto;
import com.wedul.wedulpos.user.service.UserService;
 
/**
 * User관련 컨트롤러
 * 
 * @author wedul
 *
 */
@RestController
@RequestMapping(value = "/user", method = RequestMethod.POST)
public class UserController {
    
    @Autowired
    UserService userService;
 
    /**
     * 로그인 요청
     * 
     * @param user
     * @return
     */
    @RequestMapping("/login")
    public boolean login(UserDto user) {
        return userService.login(user);    
    }
    
}
cs



그럼 이 컨트롤러 테스트를 위해 테스트 클래스를 만들어보자.


Annotation 설정

먼저 테스트 클래스를 만들기 위해서는 선 작업이 진행되어야 한다.

먼저 상위에 테스트 클래스에 대한 일부 설정값을 어노테이션으로 선언해야 한다.

SpringJUnit4ClassRunner.class
-> spring-test에서 제공하는 단위 테스트를 위한 클래스 러너

@ContextConfiguration
-> 테스트의 설정이 들어있는 xml의 위치

@Mock
-> 주입할 Service 객체를 Mock인스턴스로 선언

테스트를 진행하기전에 진행되야할 작업들은 @Before가 선언된 메서드에서 진행되어야 한다.
@Before 메서드에서는 다음과 같은 과정들이 선행되어야 한다.

@ContextConfiguration에서 함께 선언된 test를 위한 xml에는 테스트에서 사용될 bean들을 만들어주는 설정들이 들어있어야 한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
// test-config.xml에 선언된 설정 내용
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <annotation-driven />
    
    <beans:bean id="userController" class="com.wedul.wedulpos.user.controller.UserController"></beans:bean>
    <beans:bean id="userService" class="com.wedul.wedulpos.user.serviceImpl.UserServiceImpl"></beans:bean>
</beans:beans>
cs



MockMvc 객체 생성

그럼 테스트를 진행할 Controller를 이용하여 MockMvc 객체를 생성한다. 테스트전에 선 작업이 진행하는 부분이기 때문에, @before 어노테이션이 선언된 메서드에서 작업을 진행한다.



1
2
3
4
5
6
7
8
9
@Autowired
UserController userController;
 
private MockMvc mockMvc;
 
@Before
public void setUp() throws Exception {
     mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
cs



MockMvc 객체를 이용해 테스트 진행

생성된 MockMvc 객체의 perform() 메소드를 이용하여, get, put, post, delete에 대한 요청을 진행할 수 있다.

또한 ContentType 설정 및 parameter 까지 자유롭게 생성하여 테스트에 사용할 수 있다.



1
2
3
4
5
@Test
public void testUserController() throws Exception {
    // login check
    mockMvc.perform(post("/user/login").param("id", "cjung"));
}
cs



테스트 요청 결과를 검증할 수 있는 방법을 ResultAction 인터페이스에서 제공하는 메서드들을 이용하여 검증할 수 있다.


// perform 요청에대한 예측결과를 검증한다.
ResultActions andExpect(ResultMatcher matcher) throws Exception;



1
2
3
4
5
6
7
8
9
10
11
12
13
mockMvc.perform(get("/person/1"))
    .andExpect(status().isOk())
    .andExpect(content().contentType(MediaType.APPLICATION_JSON))
    .andExpect(jsonPath("$.person.name").value("Jason"))
    .andExpect(redirectedUrl("/messages/123"));
 
 mockMvc.perform(post("/form"))
    .andExpect(status().isOk())
    .andExpect(redirectedUrl("/person/1"))
    .andExpect(model().size(1))
    .andExpect(model().attributeExists("person"))
    .andExpect(flash().attributeCount(1))
    .andExpect(flash().attribute("message", "success!"));
cs



// 결과에 대해 특정한 작업을 시행함. 파라미터로 전달하는 ResultHandler를 이용하여 다양하게 동작하게 설정가능
ResultActions andDo(ResultHandler handler) throws Exception;



1
mockMvc.perform(get("/form")).andDo(print());
cs




// 결과 자체를 전달받아, Reques, Response 등에 대한 정보를 반환받을 수 있음
MvcResult andReturn();


최종 완성 예제



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.wedul.wedulpos.user.test;
 
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 
import java.nio.charset.Charset;
 
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
import com.wedul.wedulpos.user.controller.UserController;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"test-confing.xml"})
public class UserControllerTest {
    
    @Autowired
    UserController userController;
    
    private MockMvc mockMvc;
    
    private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
            MediaType.APPLICATION_JSON.getSubtype(),
            Charset.forName("utf8"));
    
    @Before
    public void setUp() throws Exception {
         mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
    }
    
    @Test
    public void testUserController() throws Exception {
        // login check
        mockMvc.perform(post("/user/login").param("id", "cjung")).andExpect(status().isOk());
        
        // 비밀번호 찾기 확인
        System.out.println(mockMvc.perform(post("/user/password/find").param("id", "cjung")).andDo(print()));
        
        /* ObjectMapper mapper = new ObjectMapper();
         * this.mockMvc.perform(post(UserController.URL_USER_CREATE)
                .contentType(contentType)
                .content(mapper.writeValueAsString(new User("wedul"))))
                .andExpect(status().isOk())
                .andDo(print());*/
    }
 
}
cs





다음 시간에는 Service 테스트 방법에 대해 알아보자.

  1. 지나가는 초보자 편집답글

    정말 감사합니다.. 상세한설명에 초보자 눈높이에 맞춰져있어서 감동했습니다.

  2. july 편집답글

    하루 반정도 헤매다가 다시 이 게시글로 돌아와서 해결했습니다ㅋㅋㅋㅋ
    감사합니다!!!!!

 [ 1 ]  [ 2 ] 

푸터바

알림

이 블로그는 구글에서 제공한 크롬에 최적화 되어있고, 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.

카운터

  • Today : 22
  • Yesterday : 503
  • Total : 68,724