-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
polish #1597
polish #1597
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,26 @@ | ||
package com.example.demo.readreplica.domain; | ||
|
||
import static com.example.demo.readreplica.domain.CommentDTO.convertToComment; | ||
|
||
import com.example.demo.readreplica.entities.Article; | ||
import com.example.demo.readreplica.entities.Comment; | ||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
|
||
public record ArticleDTO( | ||
String title, | ||
LocalDateTime authored, | ||
LocalDateTime published, | ||
List<CommentDTO> commentDTOs) {} | ||
List<CommentDTO> commentDTOs) { | ||
|
||
public Article convertToArticle() { | ||
Article article = | ||
new Article().setAuthored(authored).setTitle(title).setPublished(published); | ||
commentDTOs.forEach( | ||
commentDTO -> { | ||
Comment comment = convertToComment(commentDTO); | ||
article.addComment(comment); | ||
}); | ||
return article; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,10 @@ | ||
package com.example.demo.readreplica.domain; | ||
|
||
public record CommentDTO(String comment) {} | ||
import com.example.demo.readreplica.entities.Comment; | ||
|
||
public record CommentDTO(String comment) { | ||
|
||
static Comment convertToComment(CommentDTO commentDTO) { | ||
return new Comment().setComment(commentDTO.comment()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package com.example.demo.readreplica.controller; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import com.example.demo.readreplica.domain.ArticleDTO; | ||
import com.example.demo.readreplica.domain.CommentDTO; | ||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
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.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.test.web.servlet.assertj.MockMvcTester; | ||
|
||
@SpringBootTest | ||
@AutoConfigureMockMvc | ||
class ArticleControllerIntTest { | ||
|
||
@Autowired private MockMvcTester mvcTester; | ||
|
||
@Autowired private ObjectMapper objectMapper; | ||
|
||
@Test | ||
void findArticleById() { | ||
|
||
mvcTester | ||
.get() | ||
.uri("/articles/1") | ||
.assertThat() | ||
.hasStatusOk() | ||
.hasContentType(MediaType.APPLICATION_JSON) | ||
.bodyJson() | ||
.convertTo(ArticleDTO.class) | ||
.satisfies( | ||
articleDTO -> { | ||
assertThat(articleDTO.title()) | ||
.isNotNull() | ||
.isEqualTo("Waiter! There is a bug in my JSoup!"); | ||
assertThat(articleDTO.authored()) | ||
.isNotNull() | ||
.isInstanceOf(LocalDateTime.class); | ||
assertThat(articleDTO.published()) | ||
.isNotNull() | ||
.isInstanceOf(LocalDateTime.class); | ||
assertThat(articleDTO.commentDTOs()) | ||
.isNotNull() | ||
.hasSize(2) | ||
.hasOnlyElementsOfType(CommentDTO.class); | ||
}); | ||
} | ||
Comment on lines
+28
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance test coverage with setup and error scenarios. The test makes assumptions about existing test data and lacks coverage for error scenarios. Consider these improvements:
Example structure: private static final String TEST_ARTICLE_TITLE = "Waiter! There is a bug in my JSoup!";
@BeforeEach
void setUp() {
// Setup test data
}
@Test
void findArticleById_NotFound() {
mvcTester.get()
.uri("/articles/999")
.assertThat()
.hasStatus(HttpStatus.NOT_FOUND);
} |
||
|
||
@Test | ||
void saveArticleRetriveAndDelete() throws JsonProcessingException { | ||
ArticleDTO articleDTO = | ||
new ArticleDTO( | ||
"junitTitle", | ||
LocalDateTime.now().minusDays(1), | ||
LocalDateTime.now(), | ||
List.of(new CommentDTO("junitComment"))); | ||
AtomicReference<String> location = new AtomicReference<>(); | ||
mvcTester | ||
.post() | ||
.uri("/articles/") | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.content(objectMapper.writeValueAsString(articleDTO)) | ||
.assertThat() | ||
.hasStatus(HttpStatus.CREATED) | ||
.matches( | ||
result -> { | ||
location.set(result.getResponse().getHeader("Location")); | ||
assertThat(location.get()).isNotBlank().contains("/articles/"); | ||
}); | ||
|
||
mvcTester | ||
.get() | ||
.uri(location.get()) | ||
.assertThat() | ||
.hasStatusOk() | ||
.hasContentType(MediaType.APPLICATION_JSON) | ||
.bodyJson() | ||
.convertTo(ArticleDTO.class) | ||
.satisfies( | ||
response -> { | ||
assertThat(response.title()).isNotNull().isEqualTo("junitTitle"); | ||
assertThat(response.authored()) | ||
.isNotNull() | ||
.isInstanceOf(LocalDateTime.class); | ||
assertThat(response.published()) | ||
.isNotNull() | ||
.isInstanceOf(LocalDateTime.class); | ||
assertThat(response.commentDTOs()) | ||
.isNotNull() | ||
.hasSize(1) | ||
.hasOnlyElementsOfType(CommentDTO.class); | ||
}); | ||
|
||
mvcTester.delete().uri(location.get()).assertThat().hasStatus(HttpStatus.ACCEPTED); | ||
} | ||
Comment on lines
+57
to
+103
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Split the test method and add validation scenarios. The current test method violates the Single Responsibility Principle by testing multiple operations. Consider these improvements:
Example structure: @Test
void saveArticle_ValidData() {
ArticleDTO articleDTO = createValidArticleDTO();
// Test POST only
}
@Test
void saveArticle_InvalidData() {
ArticleDTO articleDTO = createInvalidArticleDTO();
mvcTester.post()
.uri("/articles/")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(articleDTO))
.assertThat()
.hasStatus(HttpStatus.BAD_REQUEST);
}
private ArticleDTO createValidArticleDTO() {
LocalDateTime now = LocalDateTime.now();
return new ArticleDTO(
"junitTitle",
now.minusDays(1),
now,
List.of(new CommentDTO("junitComment")));
} |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider returning ArticleDTO instead of Article entity.
Exposing JPA entities directly could lead to lazy loading issues if the entity is accessed outside the transaction boundary. Consider converting to DTO before returning.