首页 > 解决方案 > 在模拟 mvc 中发布或放置表单数据

问题描述

我想为只接受表单数据的控制器编写测试:

   @PostMapping("/signup/")
    public ResponseEntity<?> signUpUser(@ModelAttribute UserModel user, HttpServletResponse response)
            throws Exception {
        return userService.signUpUser(user, response);
    }

我曾经在邮递员中这样调用这个方法: 在此处输入图像描述

问题是我不知道如何准确模拟这个请求。

我写了一个测试,但没有说数据没有通过:

    @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");
                });
    }

标签: javaspring-bootspring-testmockmvcspring-test-mvc

解决方案


好的,我想出了解决方案。我不得不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")));
    }

}

推荐阅读