mockito 在JUnit中将嵌套列表模拟为@RequestPart

wribegjk  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(71)

我有一个Rest控制器,我需要在Springboot应用程序中编写JUnit。下面是相同的代码

@PutMapping("/update/{id}")
public void update(
        @PathVariable(name = "id") Long id,
        @RequestPart List<List<Long>> affectedIds,
        @RequestPart String compatibility,
        @RequestPart(name = "procId") String procId,
        @RequestHeader(value = "timeZone") String timeZone) {

    TimeZone userTimeZone = TimeZone.getTimeZone(timeZone);
    myService.update(
            id, affectedIds, compatibility, Long.parseLong(procId), userTimeZone);
}

我尝试编写JUnit,下面是它的代码

@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
class MyControllerTest {

    @InjectMocks
    private MyController myController;

    @Mock
    private MyService myService;

    @Autowired(required=true)
    private MockMvc mockMvc;

    @Test
    void update() throws Exception {

        Long id = 123L;
        List<List<Long>> affectedIds = List.of(
                List.of(1L, 2L),
                List.of(3L, 4L)
        );
        String compatibility = "oncecompatible";
        String procId = "11";
        String timeZone = "UTC";

        TimeZone userTimeZone = TimeZone.getTimeZone(timeZone);

        doNothing().when(myService).update(id, affectedIds, compatibility,
                Long.parseLong(procId), userTimeZone);

        ObjectMapper mapper = createObjectMapper();
        String s = mapper.writeValueAsString(affectedIds);

        ResultActions response = mockMvc.perform(MockMvcRequestBuilders.put
                ("/api/proc/check/update/{id}", id)
                .content(s)
                .content(compatibility)
                .content(procId)
                .header("timeZone", timeZone)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .accept(MediaType.APPLICATION_JSON_UTF8));

        response.andExpect(status().isOk());

    }

    private static ObjectMapper createObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        mapper.registerModule(new JavaTimeModule());
        return mapper;
    }

}

问题是,当我运行这个测试用例时,我得到了这个错误:

org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'affectedIds' is not present.

我试过其他方法,但都没有成功。我无法获取mock请求中affectedIds参数的发送方式。
P.S. -我已经根据stackoverflow的一篇文章的建议使用了ObjectMapper()。

wmvff8tz

wmvff8tz1#

您不能混合使用@SpringBootTest@InjectMocks/@Mock注解。如果这样做,Spring(以及MockMvc)将无法找到并使用正确的bean。此外,您不需要使用SpringExtension进行扩展,@SpringBootTest已经可以处理这些问题。

@SpringBootTest
@AutoConfigureMockMvc
class MyControllerTest {

    @Autowired    // <- wire from application context
    private MyController myController;

    @MockBean     // <- register mock bean in application context
    private MyService myService;

    @Autowired(required=true)
    private MockMvc mockMvc;

    // ...
}

给定代码的其他问题:

  • .content(s)覆盖之前设置的任何内容。多个调用不是累加的。您的控制器仅接收有效负载11(不带引号;引号是Java语法的一部分)。
  • @RequestPart仅用于multipart/form-data请求,但在测试中,您将content-type设置为application/json

相关问题