能否强制AssertJ采用一致内部表示来比较ProtoBuf对象?
Protobuf对象AssertJ递归比较不匹配的解决办法
问题场景
Proto消息定义
message Tags { map<string, bool> tagset = 1; } message Msg { Tags tags = 1; }
文本格式Proto文件(msg.txtpb)
tags { tagset { key: "key1" value: true } }
单元测试代码
Msg expectedProto = TextFormat.merge( new FileReader("msg.txtpb"), Msg.newBuilder()).build(); assertThat(actualProto).usingRecursiveComparison().isEqualTo(expectedProto);
错误提示
field/property 'tags_.tagsSet_.listData' differ: - actual value : null - expected value: [key: "key1" value: true] field/property 'tags_.tagSet_.mapData' differ: - actual value : {"key1"=true} - expected value: null field/property 'tags_.tagSet_.mode' differ: - actual value : MAP - expected value: LIST
解决办法
强制TextFormat以MAP模式解析
问题根源是TextFormat.merge默认用LIST模式存储map数据,和实际Proto对象的MAP模式不匹配。通过指定解析器的MapMode强制统一:TextFormat.Parser parser = TextFormat.getParser().withMapMode(TextFormat.MapMode.MAP); Msg expectedProto = parser.merge(new FileReader("msg.txtpb"), Msg.newBuilder()).build();让AssertJ忽略内部差异字段
如果不想修改解析逻辑,可在递归比较时排除这些内部实现字段:assertThat(actualProto) .usingRecursiveComparison() .ignoringFields("tags_.tagSet_.listData", "tags_.tagSet_.mapData", "tags_.tagSet_.mode") .isEqualTo(expectedProto);直接使用Protobuf原生equals方法
Protobuf自动生成的类已经实现了准确的equals逻辑,无需递归比较,直接断言更可靠:assertThat(actualProto).isEqualTo(expectedProto);
内容的提问来源于stack exchange,提问作者gph
相关产品推荐
相关产品推荐

