如何为ObjectMapper编写JUnit测试?JsonService测试异常求助
排查JsonService JUnit测试抛出ServiceException的问题
我帮你分析下这个问题,首先你的测试代码里抛出的ServiceException是被Jackson的IOException包装后的异常,从当前的异常栈看不到根本原因,但看你的TestHelper类代码,已经能定位到大概率的问题所在:
问题根源
你的TestHelper类中,成员变量id是long类型,但对应的setId方法参数却是Integer:
private long id; public void setId(Integer id) { this.id = id; }
当Jackson把TestHelper序列化为JSON时,id会被序列化为数字类型(比如1),反序列化时,Jackson默认会把这个JSON数字解析为Long类型,然后尝试调用setId(Integer)方法,这时候就会出现类型转换异常,触发IOException,进而被你的JsonService包装成ServiceException抛出。
解决步骤
先确认根本异常(可选但推荐)
你可以在测试代码里捕获ServiceException,打印它的根异常,验证我们的判断:@Test public void getObjectFromJsonTest() throws Exception { ObjectMapper mapper = new ObjectMapper(); TestHelper helper = new TestHelper(); helper.setName("name"); helper.setId(1); String json = mapper.writeValueAsString(helper); try { TestHelper actual = JsonService.getObjectFromJson(json, TestHelper.class); assertEquals(actual.getName(), "name"); assertEquals(actual.getId(), 1); } catch (ServiceException e) { // 打印根异常,确认类型转换问题 System.err.println("Root cause: " + e.getCause()); e.printStackTrace(); throw e; } }修复setter方法的类型不匹配问题
把setId方法的参数类型改成和成员变量一致的long(或者包装类Long):// 基本类型版本 public void setId(long id) { this.id = id; } // 或者包装类版本(支持null值) public void setId(Long id) { this.id = id != null ? id : 0L; }额外优化建议
- 可以给
TestHelper添加显式的无参构造方法(Jackson虽然能通过反射创建实例,但显式声明更稳妥) - 推荐使用Lombok的
@Data注解自动生成正确的getter/setter,避免手动编写时出现这类类型不匹配的错误
- 可以给
修改后再运行测试,应该就能正常反序列化,不会再抛出ServiceException了。
内容的提问来源于stack exchange,提问作者Krish
相关产品推荐
相关产品推荐

