Open so3500 opened 4 years ago
@Transaction
사용@Test
@Sql(scripts = "/test-sql/messages.sql")
@Transactional
void createMessage() throws Exception {
// given
MessageRequest req = new MessageRequest();
req.setContents("hi hello");
final String body = objectMapper.writeValueAsString(req);
// when
ResultActions action = mockMvc.perform(
post("/api/rooms/{roomId}/messages", 1)
.contentType(MediaType.APPLICATION_JSON)
.content(body));
// then
action.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.contents").value(req.getContents()));
}
@Test
@Sql(scripts = "/test-sql/messages.sql")
@DisplayName("ID가 1인 채팅방의 메시지 리스트가 조회되야만 한다")
@Transactional
void shouldGetMessageList_inRoomIdWith1() throws Exception {
mockMvc.perform(get("/api/rooms/{id}/messages", 1))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", not(empty())))
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].id", is(1)))
.andExpect(jsonPath("$[0].contents", is("foo")))
.andExpect(jsonPath("$[0].messageType", is("TEXT")));
}
shouldGetMessageList_inRoomIdWith1
테스트시 room id는 3, 4로 배정되어 message 생성 쿼리시 무결성 제약 조건 위반 org.springframework.jdbc.datasource.init.ScriptStatementFailedException:
Failed to execute SQL script statement #3 of class path resource [test-sql/messages.sql]:
INSERT INTO message(contents, message_type, created_at, room_id) VALUES ('foo', 'TEXT', '2020-08-01 00:00:00', 1);
nested exception is org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FKL1KG5A2471CV6PKEW0GDGJRMO: PUBLIC.MESSAGE FOREIGN KEY(ROOM_ID) REFERENCES PUBLIC.ROOM(ID) (1)";
SQL statement: INSERT INTO message(contents, message_type, created_at, room_id) VALUES ('foo', 'TEXT', '2020-08-01 00:00:00', 1) [23506-196]
clean-up-messages.sql
실행delete from message;
@Test
@Sql(scripts = "/test-sql/messages.sql")
@Sql(scripts = "/test-sql/clean-up-messages.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
void createMessage() throws Exception {
// given
MessageRequest req = new MessageRequest();
req.setContents("hi hello");
final String body = objectMapper.writeValueAsString(req);
// when
ResultActions action = mockMvc.perform(
post("/api/rooms/{roomId}/messages", 1)
.contentType(MediaType.APPLICATION_JSON)
.content(body));
// then
action.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.contents").value(req.getContents()));
}
@Test
@Sql(scripts = "/test-sql/messages.sql")
@Sql(scripts = "/test-sql/clean-up-messages.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
@DisplayName("ID가 1인 채팅방의 메시지 리스트가 조회되야만 한다")
void shouldGetMessageList_inRoomIdWith1() throws Exception {
mockMvc.perform(get("/api/rooms/{id}/messages", 1))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", not(empty())))
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].id", is(1)))
.andExpect(jsonPath("$[0].contents", is("foo")))
.andExpect(jsonPath("$[0].messageType", is("TEXT")));
}
@Order()
)를 지정하고 /test-sql/messages.sql
에서 생성된 message id를 테스트에서 추측해야함TestEntityManager
사용@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
@RequiredArgsConstructor
@SpringBootTest()
@Transactional
@AutoConfigureTestEntityManager
class RoomControllerIntegrationTest {
// ...
final TestEntityManager entityManager;
@Test
void createMessage() throws Exception {
// given
Room room = new Room();
room.setTitle("foo");
Room savedRoom = entityManager.persist(room);
MessageRequest req = new MessageRequest();
req.setContents("hi hello");
final String body = objectMapper.writeValueAsString(req);
// when
ResultActions action = mockMvc.perform(
post("/api/rooms/{roomId}/messages", savedRoom.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(body));
// then
action.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.contents").value(req.getContents()));
}
@Test
@DisplayName("ID가 1인 채팅방의 메시지 리스트가 조회되야만 한다")
void shouldGetMessageList_inRoomIdWith1() throws Exception {
// given
Room fooRoom = new Room();
fooRoom.setTitle("foo");
Room savedFooRoom = entityManager.persist(fooRoom);
Room barRoom = new Room();
barRoom.setTitle("bar");
entityManager.persist(barRoom);
List<Message> messages = Stream.of(1, 2, 3)
.map((id) -> {
Message message = new Message();
message.setContents("contents_" + id);
message.setMessageType(MessageType.TEXT);
message.setRoom(id % 2 == 0 ? savedFooRoom : barRoom);
return entityManager.persist(message);
}).collect(Collectors.toList());
// when, then
mockMvc.perform(get("/api/rooms/{id}/messages", fooRoom.getId()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", not(empty())))
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].id").value(messages.get(1).getId()))
.andExpect(jsonPath("$[0].contents").value(messages.get(1).getContents()))
.andExpect(jsonPath("$[0].messageType").value(messages.get(1).getMessageType().name()));
}
}
참고 링크 https://github.com/LandvibeDev/web-chat-backend/pull/24#discussion_r479663988
이 메서드를
MessageCreationTest
에 추가한 이유이 테스트를
RoomControllerIntegrationTest
에 추가할 때RoomControllerIntegrationTest#shouldGetMessageList_inRoomIdWith1
가 영향 받음하나의 클래스에서 처리할 수 없을지 고민 필요
response
error log