bookmark_borderTDD(spring) – post user

  1. TDD란?
  2. TDD의 순서
  3. Prerequisite
  4. Started with Spring Initializr
  5. Dependencies set up
  6. Write first test case for the project
    1. Test Case: Post User
    2. UserControllerTest.java 추가
    3. User.java 추가
    4. Main Class에 SecurityAutoConfiguration 추가
    5. Test Case 실행
    6. UserControllerTest.java 추가 및 @PostMapping
    7. Test Case 재 실행

TDD란?

테스트 케이스를 먼저 작성한 후 코드를 작성하는 개발 방식

TDD의 순서

  • test case를 추가
  • test case를 실행하여 실패하는지 확인
  • code를 작성
  • 테스트 실행
  • Reactor 코드
  • 위의 내용 반복

Prerequisite

  • IDE (Integrated development environment)
  • JDK 8 or later
  • Maven 3.2+

Dependencies set up

Spring Initializr를 실행하여 spring web, spring data jpa, H2 database, spring security, Lombok 추가

Write first test case for project

Test Case: Post User

  • Test Case for integration Test (real user scenario)

Delete Default TestCase in src/test/java/com/example/backend

Create UserControllerTest.java in src/test/java/com/example/backend

package com.example.hoaxify;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import com.example.hoaxify.user.User;

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
public class UserControllerTest {

    @Autowired
    TestRestTemplate testRestTemplate;

    @Test
    public void postuser_whenUserIsValidreceiveOK(){
        User user = new User();
        user.setUsername("test-user");
        user.setDisplayName("test-display");
        user.setPassword("Password");
    
        ResponseEntity<Object> response = testRestTemplate.postForEntity("/api/1.0/users", user, Object.class);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
    
    }
}
  • @SpringBootTest: This will be initializing our application for our test environment which means a web server will be started.
  • @ActiveProfiles: Spring allows us to run the application in different profiles.
  • TestRestTemplate testRestTemplate과 @Autowire 추가 하여 테스트 Client를 생성

Junit는 테스트 케이스 [@Test]를 찾아내고 각 테스트 케이스들을 실행 시킨다.

Create User.java in src/test/java/com/example/backend/user

package com.example.backend.user;

import lombok.Data;

@Data
public class User {
    private String username;
    private String displayName;
    private String password;  
}
  • 이제 setters, getters, 그리고 constructor이 필요하다. 다만, 위의 경우 lombok이 자동적으로 생성

Edit BackendApplication.java in src/main/java/com/example/backend

package com.example.backend;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class BackendApplication {

	public static void main(String[] args) {
		SpringApplication.run(BackendApplication.class, args);
	}

}
  • (exclude = SecurityAutoConfiguration.class)을 추가 함으로써 post request test case의 접근 가능

Run Test

$ mvn test
[ERROR]   UserControllerTest.postuser_whenUserIsValidreceiveOK:35 
Expecting:
 <404 NOT_FOUND>
to be equal to:
 <200 OK>
but was not.
[INFO] 
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  7.082 s
[INFO] Finished at: 2020-09-09T14:17:36+09:00
[INFO] ------------------------------------------------------------------------
  • Test Case의 End Point /api/1.0/users가 작성되어 있지 않아 Return 404

Controller를 추가하여 Test 재실행

Create UserController.java in src/test/java/com/example/backend/user

package com.example.backend.user;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @PostMapping("/api/1.0/users")
    public void createUser(){

    }
}
  • @RestController annotation 함으로써 UserController class안에 HTTP request method들 사용할 수 있음

Test Case 재 실행

[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  7.396 s
[INFO] Finished at: 2020-09-09T14:20:38+09:00

restful API를 복수형 권고함

/api/1.0/users의 API가 작성되었고, Test Case가 성공적으로 끝남.

ANOTE.DEV