테스트 전체 실행시 id 값이 4부터 시작하는 현상
1286
投稿した質問数 22
@SpringBootTest
@AutoConfigureMockMvc
@PropertySource("classpath:messages.properties")
class PostControllerTest {
@Autowired
private ObjectMapper mapper;
@Autowired
private Environment environment;
@Autowired
private MockMvc mockMvc;
@Autowired
private PostRepository postRepository;
@BeforeEach
void clean() {
postRepository.deleteAll();
}
@Test
@DisplayName("/posts 요청시 Hello World를 출력한다.")
void test() throws Exception {
// given
PostCreate request = PostCreate.builder()
.title("제목입니다.")
.content("내용입니다.")
.build();
String json = mapper.writeValueAsString(request);
// expected
mockMvc.perform(MockMvcRequestBuilders.post("/posts")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
// .content("{\"title\": \"hithere\", \"content\": \"blah\"}")
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().string(""))
.andDo(print());
}
@Test
@DisplayName("/posts 요청시 title 값은 필수다.")
void test2() throws Exception {
Class<? extends PostControllerTest> aClass = getClass();
ClassLoader classLoader = getClass().getClassLoader();
URL resource = classLoader.getResource("messages.properties");
// given
PostCreate request = PostCreate.builder()
.content("내용입니다.")
.build();
String json = mapper.writeValueAsString(request);
// expected
mockMvc.perform(MockMvcRequestBuilders.post("/posts")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
)
.andExpect(MockMvcResultMatchers.status().isBadRequest())
.andExpect(MockMvcResultMatchers.jsonPath("$.code").value("400"))
.andExpect(MockMvcResultMatchers.jsonPath("$.message").value("잘못된 요청입니다."))
.andExpect(MockMvcResultMatchers.jsonPath("$.validation.title").value(environment.getProperty("post.NotBlank")))
.andDo(print());
}
@Test
@DisplayName("/posts 요청시 db에 값이 저장된다.")
void test3() throws Exception {
// given
PostCreate request = PostCreate.builder()
.title("제목입니다.")
.content("내용입니다.")
.build();
String json = mapper.writeValueAsString(request);
// expected
mockMvc.perform(MockMvcRequestBuilders.post("/posts")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(print());
// then
assertEquals(1L, postRepository.count());
Post post = postRepository.findAll().get(0);
assertEquals("제목입니다.",post.getTitle());
assertEquals("내용입니다.",post.getContent());
}
@Test
@DisplayName("글 1개 조회")
void test4() throws Exception {
// given
Post post = Post.builder()
.title("123456789012345")
.content("bar")
.build();
postRepository.save(post);
// when
// expected
mockMvc.perform(MockMvcRequestBuilders.get("/posts/{postId}",post.getId())
.contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value(post.getId()))
.andExpect(MockMvcResultMatchers.jsonPath("$.title").value("1234567890"))
.andExpect(MockMvcResultMatchers.jsonPath("$.content").value("bar"))
.andDo(print());
// then
}
@Test
@DisplayName("글 여러개 조회")
void test5() throws Exception {
// given
List<Post> requestPosts = IntStream.range(1,31)
.mapToObj(i ->
Post.builder()
.title("title " + i)
.content("content " + i)
.build()
).collect(Collectors.toList());
postRepository.saveAll(requestPosts);
// expected
mockMvc.perform(MockMvcRequestBuilders.get("/posts?page=1&sort=id,desc")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.length()",Matchers.is(5)))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].id").value(30))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].title").value("title 30"))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].content").value("content 30"))
.andDo(print());
}
}안녕하세요 호돌맨님 질문이 있습니다.
test5를 단독으로 실행하면 문제없는데
전체를 실행했을 때는 postRepository.saveAll 전까지는 requestPosts 안에 Post가 id가 1부터 시작하는데
saveAll을 지나고 나서는 id가 4부터 시작하게됩니다.
@BeforeEach에서 postRepository.deleteAll을 수행하고 있습니다.
제생각에는
이게 Entity 의 @GeneratedValue(strategy = GenerationType.IDENTITY) 와 연관이 있는건가요?
해당 설정을 하면 말씀해주신것처럼 persist가 호출되는 시점에 id값을 db로부터 얻어오기 때문에 아무리 row가 지워졌어도 h2 내부적으로 id를1씩 증가시켜왔기에 그 증가된 값이 requestPosts 의 값도 변형시킨것이 맞나요?
回答 4
5
안녕하세요? 호돌맨입니다.
("requestPosts 안에 Post가 id가 1부터 시작하는데" 이 부분은 제가 이해하지 못했습니다. 작성하신 소스를 보면 requestsPosts의 Post데이터는 아직 id값 빌더를 통해 할당하지 않으셨기 때문에 Long 타입이라면 null이 들어가 있을것 같습니다.)
우선은 말씀하신 게 대체로 맞습니다. 정확히 @GeneratedValue(strategy = GenerationType.IDENTITY)에 직접적으로 연관이 있다기 보다도
auto increment
h2, mysql 기준으로 테이블 row를 삭제(postRepository.delete)한다고 해서 id(primary_key)가 1로 초기화 되지는 않습니다. id가 1로 초기화 되는 아래와 같습니다.
테이블이 삭제 되거나
테이블이 TRUNCATE 되거나
ALTER TABLE 명령어로 auto increment값을 1로 수정하거나
그러면 어뜨케 할까요?
.andExpect(MockMvcResultMatchers.jsonPath("$[0].id").value(30))위와같이 코드를 적더라도 id가 30이라고 보장 받을 수 없습니다.
왜냐하면 테스트가 실행되는 순서를 보장할 수 없기 때문입니다.
전체 테스트 실행시 위의 코드를 포함하는 테스트 메서드는 첫 빠따로 수행될수도 있고 마지막으로 수행될수도 있습니다.
그렇기 때문에 아래와같이 '요청한 데이터 의 id값인 requestsPosts.get(마지막index).id로 체크하는 게 좋아보입니다.
.andExpect(MockMvcResultMatchers.jsonPath("$[0].id").value(request.Posts.get(29인가 30인가).getId()))감사합니다.
Deprecated 관련 사항들
0
100
2
깃헙 collaboator 초대 관련
0
86
1
강의 듣다가 도커 이미지 생성시 각각도 가능하나 그렇게 사용하는데가 많은지 모르겠다라는 말을 듣고 남김니다
0
157
2
logout 후에 login 페이지 이동은 어디서 시켜주는건가요?
0
229
1
다중 데이터를 삭제 할 때
0
270
2
querydsl Q class 이슈
0
413
2
Windows WSL Vue 설정
2
246
1
Dip, @transactional
0
187
1
[vite] http proxy error: /auth/login
0
1041
2
로그인 하고 나서 GET요청으로 메인페이지 요청
0
234
2
GitHub Collaborator 초대 관련
0
256
2
Window에서 Vue.js 설정
0
321
2
collaboator로 초대받을 수 있을까요??
0
283
2
SecurityMockContext 로부터 유저 정보를 가져오기
0
260
1
섹션9 프론트의 코드를 보고싶습니다,,,
0
423
1
Spring Security - defaultSuccessUrl 질문
0
624
1
강의 화면이 나오지 않습니다. 음성과 자막만 나와요
0
302
1
JPAQueryFactory(em)의 객체 생성자 오류에 대해서 질문이 있습니다ㅜㅜ
0
689
2
ExceptionHandler가 AccessDeniedHandler(Http403Handler)를 먹어버리는 현상
0
1178
2
섹션10 언제 나오나요?
0
483
1
CommentService에서 Repository를 호출하지 않는데도
0
341
1
Editor....를 활용한 패턴에 질문있습니다.
0
493
1
섹션9 vue
0
451
2
Post에 edit 메서드 삼항연산자 질문
0
472
2

