#java #spring-boot #spring-test #mockmvc #spring-test-mvc
Вопрос:
Я хочу написать тест для контроллера, который принимает только данные формы:
@PostMapping("/signup/")
public ResponseEntity<?> signUpUser(@ModelAttribute UserModel user, HttpServletResponse response)
throws Exception {
return userService.signUpUser(user, response);
}
Раньше я вызывал этот метод в postman следующим образом:
Проблема в том, что я не знаю, как точно смоделировать этот запрос.
Я написал тест, но потерпел неудачу, сказав, что данные не переданы:
@Test
@Order(1)
@WithMockUser(username = "anonymousUser")
void signUpUser() throws Exception {
var user = new UserModel();
user.setEmail("email@mail.com");
MockMultipartFile file1 = new MockMultipartFile("profileFile", "hello.jpg", MediaType.IMAGE_JPEG_VALUE,
"Hello, World!".getBytes());
MockMultipartFile file2 = new MockMultipartFile("shopFile", "hello.jpg", MediaType.IMAGE_JPEG_VALUE,
"Hello, World!".getBytes());
user.setProfileFile(file1);
user.setShopFile(file2);
user.setAddress("address");
user.setDescription("desc");
user.setUserName("user n");
user.setPassword("pass1");
user.setPasswordRepeat("pass1");
mockMvc.perform(post("/api/user/signup/")
.contentType(MediaType.MULTIPART_FORM_DATA)
.accept(MediaType.APPLICATION_JSON)
.content(mapToJson(user))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$").isMap())
.andDo(print())
.andDo(result -> {
JSONObject obj = new JSONObject(result.getResponse().getContentAsString());
userId = obj.getLong("id");
});
}
Ответ №1:
Хорошо, я нашел решение. Мне пришлось использовать MockPart
класс для этих частей. Для PUT
тестирования я использовал with
метод настройки запроса на отправку PUT
запроса вместо POST
запроса. Вот примеры размещения и публикации:
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public record UserControllerTest(UserController controller,
WebApplicationContext webApplicationContext,
JwtUtils jwtUtils) {
private static Long userId;
private static MockMvc mockMvc;
private static String signupRefreshToken;
private static String signupAccessToken;
@Autowired
public UserControllerTest {
}
@BeforeAll
static void setUp() {
Authentication authentication = Mockito.mock(Authentication.class);
SecurityContext securityContext = Mockito.mock(SecurityContext.class);
Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);
}
@BeforeEach
void setUp2() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
@Order(1)
@WithMockUser(username = "anonymousUser")
void signUpUser() throws Exception {
MockMultipartFile file1 = new MockMultipartFile("profileFile", "hello.jpg", MediaType.IMAGE_JPEG_VALUE,
"Hello, World!".getBytes());
MockMultipartFile file2 = new MockMultipartFile("shopFile", "hello.jpg", MediaType.IMAGE_JPEG_VALUE,
"Hello, World!".getBytes());
MockPart address = new MockPart("address", "address".getBytes());
MockPart des = new MockPart("description", "desc".getBytes());
MockPart username = new MockPart("userName", "user n".getBytes());
MockPart password = new MockPart("password", "pass1".getBytes());
MockPart passwordRepeat = new MockPart("passwordRepeat", "pass1".getBytes());
MockPart email = new MockPart("email", "email@mail.com".getBytes());
mockMvc.perform(multipart("/api/user/signup/")
.file(file1)
.file(file2)
.part(email, des, username, address, passwordRepeat, password)
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andDo(result -> {
signupRefreshToken = result.getResponse().getHeader("refresh_token");
signupAccessToken = result.getResponse().getHeader("access_token");
JSONObject obj = new JSONObject(result.getResponse().getContentAsString());
userId = obj.getLong("id");
})
.andExpect(status().isOk())
.andExpect(jsonPath("$").isMap())
.andExpect(jsonPath("$.id").isNotEmpty());
}
@Test
@Order(4)
@WithMockUser(authorities = "OP_EDIT_USER")
void updateUser() throws Exception {
MockPart address = new MockPart("address", "UpdatedAddress".getBytes());
MockPart des = new MockPart("description", "UpdatedDesc".getBytes());
MockPart username = new MockPart("userName", "UpdatedUser n".getBytes());
MockPart id = new MockPart("id", null);
mockMvc.perform(multipart("/api/user/update/{id}/", userId)
.part(des, username, address, id)
.header("refresh_token", signupRefreshToken)
.header("access_token", signupAccessToken)
.accept(MediaType.APPLICATION_JSON)
.with(request -> {
request.setMethod("PUT");
return request;
}))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.address").value(is("UpdatedAddress")))
.andExpect(jsonPath("$.description").value(is("UpdatedDesc")))
.andExpect(jsonPath("$.userName").value(is("UpdatedUser n")));
}
}