Ok, with some experimentation, and this helpful post, I was able to cobble together a way to conditionally exclude mocked fields.
The reason I'm going to all this trouble is that out-of-the-box Gson throws an exception when it encounters Spock-mocked fields.
For Spock, my check to determine if a field is mocked is to see if the class name of the value it references contains the substring EnhancerByCGLib.
Below, ResizingArrayQueueOfStrings.arrayFactory is the field that may, or may not, be mocked.
Thankfully, I can use a single JsonSerializer for all classes that need this sort of treatment. Ideally, I wouldn't have to register the serializer for every class that might be mocked... but that's a battle for another day.
The resulting JSON, when the field is mocked and ResizingArrayQueueOfStrings is serialized, is
queue {
"arrayFactory": "** mocked **",
}
otherwise, it's
queue {
"arrayFactory": {},
}
Hope this helps others with a similar need.
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);
}
}