我有以下控制器:
RestApiController.java
package com.spring.ocr.rest.restconsume.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;
import com.spring.ocr.rest.restconsume.model.User;
import com.spring.ocr.rest.restconsume.service.UserService;
import com.spring.ocr.rest.restconsume.util.CustomErrorType;
@RestController
@RequestMapping("/api")
public class RestApiController {
@Autowired
UserService userService;
@RequestMapping(method = RequestMethod.GET, value = "/user/")
public ResponseEntity<List<User>> listAllUsers() {
final List<User> users = userService.findAllUsers();
if(users.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<List<User>>(users, HttpStatus.OK);
}
@RequestMapping(method = RequestMethod.GET, value = "/user/{id}")
public ResponseEntity<?> getUser(@PathVariable("id") long id) {
final User user = userService.findUserById(id);
if(user == null) {
return new ResponseEntity<>(new CustomErrorType(String.format("User with id %s not found", id)), HttpStatus.NOT_FOUND);
}
return new ResponseEntity<User>(user, HttpStatus.OK);
}
@RequestMapping(method = RequestMethod.POST, value = "/user/")
public ResponseEntity<?> createUser(@RequestBody User user, UriComponentsBuilder ucBuilder) {
if(userService.doesUserExist(user)) {
return new ResponseEntity<>(new CustomErrorType(String.format("Unable to create, user %s already exists", user.getName())), HttpStatus.CONFLICT);
}
userService.createUser(user);
final HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/api/user/{id}").buildAndExpand(user.getId()).toUri());
return new ResponseEntity<String>(headers, HttpStatus.CREATED);
}
@RequestMapping(method = RequestMethod.PUT, value = "/user/{id}")
public ResponseEntity<?> updateUser(@PathVariable("id") long id,@RequestBody User user) {
User currentUser = userService.findUserById(id);
if(currentUser == null) {
return new ResponseEntity<>(new CustomErrorType(String.format("Unable to create update, User with id %s not found", user.getId())), HttpStatus.NOT_FOUND);
}
currentUser.setName(user.getName());
currentUser.setAge(user.getAge());
currentUser.setSalary(user.getSalary());
userService.updateUser(currentUser);
return new ResponseEntity<User>(currentUser, HttpStatus.OK);
}
@RequestMapping(method = RequestMethod.DELETE, value = "/user/{id}")
public ResponseEntity<?> deleteUser(@PathVariable("id") long id) {
User user = userService.findUserById(id);
if(user == null) {
return new ResponseEntity<>(new CustomErrorType(String.format("Unable to delete user, user with id %s not found", id)), HttpStatus.NOT_FOUND);
}
userService.deleteUserById(id);
return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
}
@RequestMapping(method = RequestMethod.DELETE, value = "/user/")
public ResponseEntity<User> deleteAllUsers() {
userService.deleteAllUsers();
return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
}
}
我已经使用mockMvc设置了对网络图层的测试,用户服务bean被模拟为标准:
RestApiControllerUnitTest.java
package com.spring.ocr.rest.restconsume.controller;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.doNothing;
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.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
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.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
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.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.spring.ocr.rest.restconsume.model.User;
import com.spring.ocr.rest.restconsume.service.UserService;
@RunWith(SpringRunner.class)
@WebMvcTest(RestApiController.class)
public class RestApiControllerUnitTest {
@Autowired
private MockMvc mockMvc;
@MockBean
UserService userService;
@Autowired
ObjectMapper objectMapper;
private final List<User> dummyUserList = getDummyUserList();
private final User dummyUser = new User((long)1, "Dave", (short)30, (double)30000);
private final User dummyUpdatedUser = new User((long)1, "David", (short)31, (double)35000);
@Test
public void test_listAllUsers_userListSizeIs4_returnsListSizeOf4AndOkStatus() throws Exception {
when(userService.findAllUsers()).thenReturn(dummyUserList);
this.mockMvc.perform(get("/api/user/"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(4)));
}
@Test
public void test_listAllUsers_userListIsEmpty_returnsNoContentStatus() throws Exception {
when(userService.findAllUsers()).thenReturn(new ArrayList<User>());
this.mockMvc.perform(get("/api/user/"))
.andDo(print())
.andExpect(status().isNoContent());
}
@Test
public void test_getUser_userExists_returnsUser() throws Exception {
when(userService.findUserById(dummyUser.getId())).thenReturn(dummyUser);
this.mockMvc.perform(get("/api/user/" + dummyUser.getId()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.id",is((int)dummyUser.getId())))
.andExpect(jsonPath("$.name", is(dummyUser.getName())))
.andExpect(jsonPath("$.age", is((int)dummyUser.getAge())))
.andExpect(jsonPath("$.salary", is(dummyUser.getSalary())));
}
@Test
public void test_getUser_userDoesntExist_returnsNotFoundStatusAndCustomErrorString() throws Exception {
when(userService.findUserById(dummyUser.getId())).thenReturn(null);
this.mockMvc.perform(get("/api/user/"+dummyUser.getId()))
.andDo(print())
.andExpect(status().isNotFound())
.andExpect(content().string(containsString("User with id 1 not found")));
}
@Test
public void test_createUser_userDoesNotExist_userCreated() throws Exception {
final String dummyUserJson = objectMapper.writeValueAsString(dummyUser);
when(userService.doesUserExist(dummyUser)).thenReturn(false);
MvcResult result = this.mockMvc.perform(post("/api/user/")
.contentType(MediaType.APPLICATION_JSON)
.content(dummyUserJson))
.andDo(print())
.andExpect(status().isCreated())
.andReturn();
final String header = result.getResponse().getHeader("Location");
assertThat(header, is("http://localhost/api/user/1"));
}
@Test
public void test_createUser_userExists_returnsNotFoundStatusAndCustomErrorMessage() throws Exception {
final String dummyUserJson = objectMapper.writeValueAsString(dummyUser);
final String expectedContent = String.format("Unable to create, user %s already exists", dummyUser.getName());
when(userService.doesUserExist(anyObject())).thenReturn(true);
this.mockMvc.perform(post("/api/user/")
.contentType(MediaType.APPLICATION_JSON)
.content(dummyUserJson))
.andDo(print())
.andExpect(status().isConflict())
.andExpect(jsonPath("$.errorMessage", is(expectedContent)));
}
@Test
public void test_updateUser_userExists_returnsOkStatusAndUpdatedUser() throws Exception {
final String dummyUpdatedUserJson = objectMapper.writeValueAsString(dummyUpdatedUser);
when(userService.findUserById(dummyUser.getId())).thenReturn(dummyUser);
doNothing().when(userService).updateUser(dummyUser);
this.mockMvc.perform(put("api/user/" + dummyUser.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(dummyUpdatedUserJson))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.age", is(dummyUpdatedUser.getAge())))
.andExpect(jsonPath("$.name", is(dummyUpdatedUser.getName())))
.andExpect(jsonPath("$.salary", is(dummyUpdatedUser.getSalary())));
}
@Test
public void test_deleteUser_userExists_returnNoContentStatus() throws Exception {
when(userService.findUserById(dummyUser.getId())).thenReturn(dummyUser);
this.mockMvc.perform(delete("api/user/" + dummyUser.getId()))
.andDo(print())
.andExpect(status().isNotFound());
}
@Test
public void test_deleteUser_userDoesntExist_returnsNotFoundStatusAndCustomErrorMessage () throws Exception {
when(userService.findUserById(dummyUser.getId())).thenReturn(null);
final String expectedContent = String.format("Unable to create update, User with id %s not found", dummyUser.getName());
this.mockMvc.perform(delete("api/user/"+dummyUser.getId()))
.andDo(print())
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.errorMessage", is(expectedContent)));
}
@Test
public void test_deleteAllUsers_usersListPopulated_returnNoContentStatus() throws Exception {
this.mockMvc.perform(delete("api/user/").contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isNotFound());
}
private List<User> getDummyUserList() {
final List<User> dummyUserList = new ArrayList<>();
dummyUserList.add(new User((long)1, "Dave", (short)30, (double)30000));
dummyUserList.add(new User((long)2, "Jess", (short)20, (double)20000));
dummyUserList.add(new User((long)3, "Mike", (short)40, (double)40000));
dummyUserList.add(new User((long)4, "Molly", (short)50, (double)50000));
return dummyUserList;
}
}
测试test_updateUser_userExists_returnsOkStatusAndUpdatedUser
返回404而不是200状态,而test_deleteUser_userDoesntExist_returnsNotFoundStatusAndCustomErrorMessage
未返回正文中的错误消息,这暗示404不是&#34;真正的&#34 ; 404(它没有返回,因为正确的响应返回,它由于其他原因返回它)。我还认为其他404个状态可能会在相同的上下文中返回。
答案 0 :(得分:0)
问题是由于在失败的测试中使用的控制器方法上缺少“/”。