我正在尝试逐步优化我从互联网上获得的示例。因此,我从单元测试开始。我想用SpringBoot和Mockito编写单元测试,就像这里的https://spring.io/guides/gs/testing-web/所示的最后一个例子。
在我的代码中,我有一个控制器,一个DAO和一个服务。我想对控制器的2种方法进行单元测试,例如一个带有POST,另一个带有PUT。但是以某种方式没有提交内容。
我要进行单元测试的控制器方法:
@PostMapping("/article")
public ResponseEntity<Void> addArticle(@RequestBody Article article, UriComponentsBuilder builder) {
boolean isArticleAdded = articleService.addArticle(article);
if (isArticleAdded == false) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}
HttpHeaders headers = new HttpHeaders();
headers.setLocation(builder.path("/article/{id}").buildAndExpand(article.getArticleId()).toUri());
return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
}
@PutMapping("/article/{id}")
public ResponseEntity<Article> updateArticle(@PathVariable Integer id, @RequestBody Article article) {
boolean isArticleUpdated = articleService.updateArticle(id, article);
if (!isArticleUpdated) {
return new ResponseEntity<Article>(HttpStatus.CONFLICT);
}
article.setArticleId(id);
return new ResponseEntity<Article>(article, HttpStatus.OK);
}
服务中的相应方法:
@Override
public synchronized boolean addArticle(Article article){
if (articleDAO.articleExists(article.getTitle(), article.getCategory())) {
return false;
} else {
articleDAO.addArticle(article);
return true;
}
}
@Override
public boolean updateArticle(Integer articleID, Article article) {
if (articleDAO.articleExists(article.getTitle(), article.getCategory())) {
return false;
} else {
articleDAO.updateArticle(articleID, article);
return true;
}
}
我已经优化的存储库中的代码:
@Override
public void addArticle(Article article) {
articleRepo.save(article);
}
@Override
public void updateArticle(int articleID, Article article) {
articleRepo.findById(articleID)
.map(artcl -> {
artcl.setTitle(article.getTitle());
artcl.setCategory(article.getCategory());
return articleRepo.save(artcl);
})
.orElseGet(() -> articleRepo.save(article));
}
和我的测试:
@RunWith(SpringRunner.class)
@WebMvcTest(ArticleController.class)
public class WeblayerTests {
private static Logger log = LoggerFactory.getLogger(WeblayerTests.class);
@Autowired
private MockMvc mockMvc;
@MockBean
private ArticleService articleServ;
@Test
public void testUpdateArticles() throws Exception {
Article article = new Article(2, "Spring Boot and Docker", "Docker");
when(articleServ.updateArticle(2, article)).thenReturn(true);
mockMvc.perform(MockMvcRequestBuilders.put("/article/2").accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
.content(asJSONString(article)))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk());
}
@Test
public void testAddArticles() throws Exception {
Article article = new Article(2, "Spring Boot and Docker", "Docker");
when(articleServ.addArticle( article)).thenReturn(true);
log.info("the JSON-String: {}", asJSONString(article));
mockMvc.perform(MockMvcRequestBuilders.post("/articles").content(asJSONString(article)))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk());
}
public static String asJSONString(final Object obj) {
try {
return new ObjectMapper().writeValueAsString(obj);
} catch (JsonProcessingException e) {
log.error(e.getMessage());
throw new RuntimeException();
}
}
但是由于内容主体未提交,所以某种程度上测试失败了。在控制台上,我收到以下请求:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /articles
Parameters = {}
Headers = []
Body = <no character encoding set>
Session Attrs = {}
MockHttpServletRequest:
HTTP Method = PUT
Request URI = /article/2
Parameters = {}
Headers = [Accept:"application/json;charset=UTF-8"]
Body = <no character encoding set>
Session Attrs = {}
我做错了什么?谢谢你的帮助