使用Kotlin与JUnit 5测试Rest API插入接口失败问题
解决JUnit 5测试Rest API插入接口的InvalidMediaTypeException问题
嘿,我一眼就瞅见你代码里的问题了——你把请求体的JSON字符串错误地传给了contentType()方法,这直接导致了那个烦人的InvalidMediaTypeException!让我帮你一步步把问题捋顺:
1. 修正请求体的设置方式
你连续调用了两次.contentType(),第二次本该用.content()来传递JSON格式的请求体,结果误把JSON字符串当成了媒体类型传入,这可不就报错了嘛:
错误代码片段
.contentType(MediaType.APPLICATION_JSON_UTF8) .contentType(ObjectMapper().registerModule(JavaTimeModule()).let { it.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); it.writeValueAsString(lp) })
修正后代码
.contentType(MediaType.APPLICATION_JSON_UTF8) .content(ObjectMapper().registerModule(JavaTimeModule()).let { it.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) it.writeValueAsString(lp) })
2. 修复控制器的返回值逻辑
你的控制器里返回ResponseEntity.ok().body(HttpStatus.CREATED),这会把响应状态码设为200 OK,同时把HttpStatus.CREATED当成响应体返回,和你测试里期望的isCreated(201状态码)完全不符。应该直接返回201状态码:
修改后的控制器代码
override fun insert(@Valid @RequestBody model: LegalPersonModel): ResponseEntity<Any> { service.insert(service.modelToEntity(model)) // 直接返回201创建成功的状态码,不需要额外的body return ResponseEntity.status(HttpStatus.CREATED).build() // 如果需要返回新建资源的地址,可以用下面的写法(需要补充资源ID) // return ResponseEntity.created(URI.create("/api/clients/lp/${新建资源的ID}")).build() }
3. 修正Mock Service的参数匹配
控制器里调用service.insert(service.modelToEntity(model)),传入的是从LegalPersonModel转换来的LegalPerson实体,但你测试里mock的是service.insert(lp)——这里很可能因为参数不匹配导致mock失效。可以用any()来匹配任意LegalPerson对象,避免这个问题:
修正后的Mock代码
Mockito.doReturn(lp).`when`(service)!!.insert(Mockito.any(LegalPerson::class.java))
4. 优化测试代码可读性
把ObjectMapper的配置抽出来复用,避免每次测试都重复初始化:
// 放到测试类的成员变量位置 private val objectMapper = ObjectMapper() .registerModule(JavaTimeModule()) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) @Test fun insert() { Mockito.doReturn(lp).`when`(service)!!.insert(Mockito.any(LegalPerson::class.java)) mockMvc?.perform(MockMvcRequestBuilders.post("/api/clients/lp") .contentType(MediaType.APPLICATION_JSON_UTF8) .content(objectMapper.writeValueAsString(lp))) ?.andExpect(MockMvcResultMatchers.status().isCreated) ?.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) }
调整完这些之后,你的测试应该就能正常跑通,不会再出现媒体类型无效的错误啦。
内容的提问来源于stack exchange,提问作者Rodrigo Batista
相关产品推荐
相关产品推荐

