스프링

 

controller

package com.cos.demo.web;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.cos.demo.domain.Book;
import com.cos.demo.service.BookService;

import lombok.RequiredArgsConstructor;


@RequiredArgsConstructor
@RestController
public class BookController {
	
	private final BookService bookService;
	
	@PostMapping("/book")
	public ResponseEntity<?> save(@RequestBody Book book){			
		return new ResponseEntity<>(bookService.saveBook(book), HttpStatus.CREATED);
	}
	
	@GetMapping("/book")
	public ResponseEntity<?> findAll(){		
		return new ResponseEntity<>(bookService.getAllBook(), HttpStatus.OK);
	}
	
	@GetMapping("/book/{id}")
	public ResponseEntity<?> findById(@PathVariable Long id){		
		return new ResponseEntity<>(bookService.getBook(id), HttpStatus.OK);	
	}
		
	@PutMapping("/book/{id}")
	public ResponseEntity<?> update(@PathVariable Long id, @RequestBody Book book){
		return new ResponseEntity<>(bookService.getBook(id), HttpStatus.OK);
	}

	@DeleteMapping("/book/{id}")
	public ResponseEntity<?> deleteById(@PathVariable Long id){	
		return new ResponseEntity<>(bookService.deletBook(id), HttpStatus.OK);
	}
		
}



 

 

1. 통합테스트 - BookControllerItegreTest

package com.cos.demo.web;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;

import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.transaction.annotation.Transactional;

import com.cos.demo.domain.Book;
import com.cos.demo.domain.BookRepository;
import com.cos.demo.service.BookService;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

/**
 * 통합테스트 (모든 Bean 들을 똑같이 IOC 에 올리고 테스트하는 것)
 * WebEnvironment.MOCK=실제 톰켓을 올리는것이 아니라, 다른 톰켓으로 테스트
 * WebEnvironment.RANDOM_PORT = 실제 톰켓으로 테스트
 * 
 * @AutoConfigureMockMvc MockMvc 를 IOC 에 등록해줌.
 * @Transactional 은 각각의 테스트함수가 종료될 때만다 트랜잭션을 rollback 해주는 어노테이션
 */
@Slf4j
@Transactional
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = WebEnvironment.MOCK) 
public class BookControllerItegreTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @Autowired
    private BookRepository bookRepository;
    
    @Autowired
    private EntityManager entityManager;
    
    
//    @BeforeEach
//    public void init(){
//        List<Book> books =new ArrayList<Book>();
//        books.add(new Book(null,"스프링부트 따라하기","코스"));
//        books.add(new Book(null,"리엑트 따라하기","코스"));
//        books.add(new Book(null,"JUnit 따라하기","코스"));
//        bookRepository.saveAll(books);
//        entityManager.createNativeQuery("ALTER TABLE book ALTER COLUMN id RESTART WITH 1").executeUpdate();
//        //entityManager.createNativeQuery("ALTER TABLE book AUTO_INCREMENT=1").executeUpdate();
//    }
//    
//    @AfterEach
//    public void end(){
//        bookRepository.deleteAll();
//    }
    
    
    @Test
    public void save_테스트() throws Exception {
        log.info("save_테스트() 시작 ==========================");
        //given (테스트를 하기 위한 준비)
        Book book=new Book(null, "스프링 따라하기", "코스");
        String content=new ObjectMapper().writeValueAsString(book);
        log.info(content);
        
        
        //when(테스트 실행)
        ResultActions resultActions =mockMvc.perform(post("/book").contentType(
                MediaType.APPLICATION_JSON).content(content).accept(MediaType.APPLICATION_JSON));
        
        
        //then(검증)  //https://jsonpath.com/
        resultActions
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.title").value("스프링 따라하기"))
            .andDo(MockMvcResultHandlers.print());        
    }
    
    
    
    
    @Test
    public void findAll_테스트() throws Exception{
        //given
        List<Book> books=new ArrayList<>();
        books.add(new Book(1L,"스프링부트 따라하기", "코스"));
        books.add(new Book(2L,"리엑트 따라하기", "코스"));        
        
        bookRepository.saveAll(books);
        
        //when
        ResultActions resultActions=mockMvc.perform(get("/book")
                .accept(MediaType.APPLICATION_JSON));
            
        //공식문서 : https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing
        //https://jsonpath.com/
        //then 
        resultActions
            .andExpect(status().isOk())
            .andExpect(jsonPath("$", Matchers.hasSize(2)))
            .andExpect(jsonPath("$.[0].title").value("스프링부트 따라하기"))
            .andDo(MockMvcResultHandlers.print());        
    }
    
    
    
    @Test
    public void findById_테스트() throws Exception{                
        List<Book> books =new ArrayList<Book>();
        books.add(new Book(null,"스프링부트 따라하기","코스"));
        books.add(new Book(null,"리엑트 따라하기","코스"));
        books.add(new Book(null,"JUnit 따라하기","코스"));
        bookRepository.saveAll(books);
        
        Long id=1L;
        
        ResultActions resultActions=mockMvc.perform(get("/book/{id}", id)
                .accept(MediaType.APPLICATION_JSON));
        
        //then
        resultActions
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.title").value("스프링부트 따라하기"))
            .andDo(MockMvcResultHandlers.print());                
    }
    
    
    @Test
    public void update_테스트() throws Exception{
        Long id=1L;
        List<Book> books =new ArrayList<Book>();
        books.add(new Book(null,"스프링부트 따라하기","코스"));
        books.add(new Book(null,"리엑트 따라하기","코스"));
        books.add(new Book(null,"JUnit 따라하기","코스"));
        bookRepository.saveAll(books);
        
        
        Book book=new Book(id, "C++ 따라하기","코스");
        String content=new ObjectMapper().writeValueAsString(book);
        //영속성 객체 가져오기
        Book entitiy=bookRepository.findById(id).orElseThrow(()->new IllegalArgumentException("ID 를 찾을 수 없습니다."));
        entitiy.setTitle(book.getTitle());
        
    
        //when
        ResultActions resultActions=mockMvc.perform(
                put("/book/{id}", id)
                .contentType(MediaType.APPLICATION_JSON)
                .content(content)
                .accept(MediaType.APPLICATION_JSON));
            
        
        //공식문서 : https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing
        //https://jsonpath.com/
        //then 
        resultActions
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.title").value("C++ 따라하기"))
            .andDo(MockMvcResultHandlers.print());                        
    }
    
    
    
    @Test
    public void delete_테스트() throws Exception{    
        Long id=1L;
        Book book=new Book(id, "C++ 따라하기","코스");
        bookRepository.save(book);
        
        //삭제처리시 예상값
        //when(bookService.deletBook(id)).thenReturn("ok");
                
        //when
        ResultActions resultActions=mockMvc.perform(delete("/book/{id}", id)
                .accept(MediaType.TEXT_PLAIN));
        
        //then
        resultActions
        .andExpect(status().isOk())
        .andDo(MockMvcResultHandlers.print());
                
        MvcResult requestResult=resultActions.andReturn();
        String result=requestResult.getResponse().getContentAsString();
        
        log.info("1.resultActions  ==>{}", resultActions);
        log.info("2.result  ==>{}", result);        
        assertEquals("ok", result);            
    }
    
    
    
}



 

 

2. 단위 테스트 -BookControllerUnitTest 

package com.cos.demo.web;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.ArrayList;
import java.util.List;

import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;

import com.cos.demo.domain.Book;
import com.cos.demo.service.BookService;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

//단위테스트(Controller 관련 로직만 띄우기) Filter, ControllerAdvice
@Slf4j
//@Transactional
@WebMvcTest
public class BookControllerUnitTest {

    @Autowired
    private MockMvc mockMvc;
    
    @MockBean //IoC 환경에 bean 등록됨.
    private BookService bookService;
    
    //BDDMockito 패턴 given, when, then
    @Test
    public void save_테스트() throws Exception {
        log.info("save_테스트() 시작 ==========================");
        //given (테스트를 하기 위한 준비)
        Book book=new Book(null, "스프링 따라하기", "코스");
        String content=new ObjectMapper().writeValueAsString(book);
        log.info(content);
        
        //결과값을 미리 설정
        when(bookService.saveBook(book)).thenReturn(new Book(1L,"스프링 따라하기", "코스"));
        
        
        //when(테스트 실행)
        ResultActions resultActions =mockMvc.perform(post("/book").contentType(
                MediaType.APPLICATION_JSON).content(content).accept(MediaType.APPLICATION_JSON));
        
        
        //then(검증)  //https://jsonpath.com/
        resultActions
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.title").value("스프링 따라하기"))
            .andDo(MockMvcResultHandlers.print());        
    }
    
    
    @Test
    public void findAll_테스트() throws Exception{
        //given
        List<Book> books=new ArrayList<>();
        books.add(new Book(1L,"스프링부트 따라하기", "코스"));
        books.add(new Book(2L,"리엑트 따라하기", "코스"));        
        
        //결과값을 미리 설정
        when(bookService.getAllBook()).thenReturn(books);
                
        //when
        ResultActions resultActions=mockMvc.perform(get("/book")
                .accept(MediaType.APPLICATION_JSON));
            
        //공식문서 : https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing
        //https://jsonpath.com/
        //then 
        resultActions
            .andExpect(status().isOk())
            .andExpect(jsonPath("$", Matchers.hasSize(2)))
            .andExpect(jsonPath("$.[0].title").value("스프링부트 따라하기"))
            .andDo(MockMvcResultHandlers.print());        
    }
    

    @Test
    public void findById_테스트() throws Exception{        
        Long id=1L;
        when(bookService.getBook(id)).thenReturn(new Book(1L, "자바 공부하기", "쌀"));
                
        ResultActions resultActions=mockMvc.perform(get("/book/{id}", id)
                .accept(MediaType.APPLICATION_JSON));
        
        //then
        resultActions
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.title").value("자바 공부하기"))
            .andDo(MockMvcResultHandlers.print());                
    }
    
    
    
    
    @Test
    public void update_테스트() throws Exception{
        Long id=1L;
        Book book=new Book(id, "C++ 따라하기","코스");
        String content=new ObjectMapper().writeValueAsString(book);
    
        //결과값을 미리 설정
        when(bookService.updateBook(id,book)).thenReturn(new Book(id,"C++ 따라하기","코스"));
        
        //when
        ResultActions resultActions=mockMvc.perform(
                put("/book/{id}", id)
                .contentType(MediaType.APPLICATION_JSON)
                .content(content)
                .accept(MediaType.APPLICATION_JSON));
                
        //공식문서 : https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing
        //https://jsonpath.com/
        //then 
        resultActions
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.title").value("C++ 따라하기"))
            .andDo(MockMvcResultHandlers.print());                        
    }
    
    
    
    
    @Test
    public void delete_테스트() throws Exception{    
        Long id=1L;
        Book book=new Book(id, "C++ 따라하기","코스");
        bookService.saveBook(book);
        
        //삭제처리시 예상값
        when(bookService.deletBook(id)).thenReturn("ok");
                
        //when
        ResultActions resultActions=mockMvc.perform(delete("/book/{id}", id)
                .accept(MediaType.TEXT_PLAIN));
        
        //then
        resultActions
        .andExpect(status().isOk())
        .andDo(MockMvcResultHandlers.print());
                
        MvcResult requestResult=resultActions.andReturn();
        String result=requestResult.getResponse().getContentAsString();
        
        log.info("1.resultActions  ==>{}", resultActions);
        log.info("2.result  ==>{}", result);        
        assertEquals("ok", result);            
    }
    
    
    
    
}



 

 

 

3. 서비스  - BookServiceUnitTest

package com.cos.demo.service;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import com.cos.demo.domain.BookRepository;

//단위테스트(Controller, Filter, ControllerAdvice)
//BookRepository => 가짜 객체로 만들 수 있음.
@ExtendWith(MockitoExtension.class)
public class BookServiceUnitTest {

    @InjectMocks //BookService 객체가 만들어 질때 BookServiceUnitTest 파일에     @Mock 로 등록된 모든 애들을 주입받는다.
    private BookService bookService;
    
    @Mock
    private BookRepository bookRepository;
    
    @Test
    public void save_테스트(){        
    
    }
    
}

 

 

 

4. Repository  - BookRepositoryUnitTest

package com.cos.demo.domain;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.transaction.annotation.Transactional;

//단위테스트(Controller, Filter, ControllerAdvice
@Transactional
@AutoConfigureTestDatabase(replace = Replace.ANY) //Replace.ANY 가짜 디비로 테스트, Replace.None 실제 DB 로 테스트
@DataJpaTest() //Repository 들을 다 IOC 등록해둠.
public class BookRepositoryUnitTest {

    
    @Autowired
    private BookRepository bookRepository;
    
    
    @Test
    public void save_테스트(){        
        Book book=new Book(null,"책제목1","책저자1");        
        Book bookEntity=bookRepository.save(book);        
        assertEquals("책제목1", bookEntity.getTitle());        
    }
    
    
    
}

 

 

 

1.

 

2.

 

 

3.

 

 

4.

 

 

 

about author

PHRASE

Level 60  라이트

당신이 알고 있는 가장 밝고 정열적인 사람이 되라

댓글 ( 4)

댓글 남기기

작성