好的,通过一些实验和this helpful post,我能够拼凑出一种有条件地排除模拟字段的方法。
我要解决所有这些麻烦的原因是开箱即用的 Gson 在遇到 Spock 模拟字段时会引发异常。
对于Spock,我确定一个字段是否被模拟的检查是查看它引用的值的类名是否包含子字符串EnhancerByCGLib。
下面,ResizingArrayQueueOfStrings.arrayFactory 是可能会或可能不会被模拟的字段。
谢天谢地,我可以为所有需要这种处理的课程使用一个 JsonSerializer。理想情况下,我不必为每个可能被嘲笑的类注册序列化程序......但这是另一天的战斗。
当字段被模拟并且ResizingArrayQueueOfStrings被序列化时,生成的JSON是
queue {
"arrayFactory": "** mocked **",
}
否则就是
queue {
"arrayFactory": {},
}
希望这可以帮助其他有类似需求的人。
public class MockSerializer implements JsonSerializer<Object> {
@Override
public JsonElement serialize(Object src, Type typeOfSrc, JsonSerializationContext context) {
Gson gson = new Gson();
String className = src.getClass().getName();
boolean isMocked = className.contains("EnhancerByCGLIB");
if (isMocked) return new JsonPrimitive("** mocked **");
else return gson.toJsonTree(src);
}
}
public class ResizingArrayQueueOfStrings {
private ArrayFactory arrayFactory;
public String toString() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(ArrayFactory.class, new MockSerializer())
.setPrettyPrinting()
.create();
return gson.toJson(this);
}
}