Wpadłem na ten problem podczas testowania kontrolera Spring za pomocą MockMvc, Mockito i Jacksona, więc zrobiłem prostą klasę, aby przetestować zachowanie Jacksona. Używam jackson-databind: 2.3.1 i mockito-core: 1.9.5.Nieskończona rekursja podczas serializacji obiektów z Jackson i Mockito
Biorąc pod uwagę tę klasę:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.Serializable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class Person implements Serializable {
private String name;
private int age;
// Public getters and setters...
public static void main(String[] args) {
String name = "Bob";
int age = 21;
ObjectMapper objectMapper = new ObjectMapper();
// attempt serialization with real object
Person person = new Person();
person.setName(name);
person.setAge(age);
try {
System.out.println(objectMapper.writeValueAsString(person));
} catch (JsonProcessingException e) {
e.printStackTrace();
System.err.println("Failed to serialize real object");
}
// attempt serialization with mock object
Person mockPerson = mock(Person.class);
when(mockPerson.getName()).thenReturn(name);
when(mockPerson.getAge()).thenReturn(age);
try {
System.out.println(objectMapper.writeValueAsString(mockPerson));
} catch (JsonProcessingException e) {
e.printStackTrace();
System.err.println("Failed to serialize mock object.");
}
}
Jackson ma problemu szeregowania rzeczywistego obiektu, jednak będzie ona rzucać JsonMappingException kiedy próbuje serializować szydzili obiekt. Debugowanie kodu powoduje wielokrotne wywoływanie serializeFields (bean, jgen, provider), utknięcie w wewnętrznych właściwościach Mockito.
Moje pytanie brzmi: czy mimo to zmusić Jacksona do użycia metod gettera? Próbowałem @JsonIgnoreProperties na klasie, @JsonIgnore na polach i @JsonProperty na metodach (w różnych kombinacjach, bez powodzenia). Czy muszę napisać własny niestandardowy serializator?
Dzięki!
Gdzie są Twoje metody gettera? –
Są w kodzie! Właśnie je wykluczyłem dla czytelności - po prostu zwracają wartość prywatnego pola w tym przykładzie. –
jackson użyje metody getter, ale te muszą być zgodne z konwencjami nazewnictwa –