JSON을 추상 유형으로 역 직렬화 할 수 없습니다.
JSON 문자열을 역 직렬화하는 테스트를 실행할 때 오류 메시지가 표시됩니다.
JSON을 추상 유형으로 역 직렬화 할 수 없음 : TestController.Item
JSON에는 추상적 인 객체 목록이 포함되어 있으며 역 직렬화 할 수 없습니다.
public class TestController {
@Testvisible
private abstract class Item{
public String bla;
public String bla2;
}
public class SomeItem extends Item{
private SomeItem() {
bla = 'bla';
}
}
public class SomeClass{
@Testvisible private List<Item> items;
public Graph(List<SomeItem> someItems) {
items = new List<Item>();
items.addAll((List<Item>) someItems);
}
}
}
이것은 테스트 클래스입니다.
@IsTest
public class TestController_Test {
@IsTest
private static void testSomething() {
TestController.SomeClass someClass = (TestController.SomeClass) System.JSON.deserialize(json, TestController.SomeClass.class);
for(TestController.Item item : someClass.items) {
}
}
}
동일한 오류가 있는 github pull 요청 을 찾았습니다 . 거기입니다 중요 업데이트 와 나는이 문제를 일으키는 것을 확신합니다.
그 문제를 해결하는 방법을 알고 있습니까?
답변
이 코드가 컴파일되고 실행될 때에도 문제가있었습니다. JSON 파서는 실제로 사용하려는 하위 유형을 알지 못하기 때문에 Item 목록 내에서 SomeItem을 실제로 인스턴스화 할 수 없습니다.
따라서 중요 업데이트는 이러한 유형의 코드로 비정상적인 동작을 수정하기 때문에 실제로 좋은 것입니다. 해결책은 메모리에 개체를 수동으로 만드는 것입니다.
이것은 또한 JSON을 사용하는 일종의 API와 함께 사용되는 경우 가능한 설계 결함을 가리 킵니다. 시스템이 데이터 유형에 사용할 올바른 유형의 하위 클래스를 결정할 수없고 Apex와 같은 강력한 유형의 언어에서는 문제가되기 때문에 작동하지 않습니다.
모든 것이 TestVisible로 표시되어 있으므로 올바른 솔루션은 수동으로 개체를 만드는 것입니다.
TestController.SomeClass wrapper = new TestController.SomeClass();
wrapper.items = new TestController.SomeItem[0];
wrapper.items.add(new TestController.SomeItem());
// etc //
요약하면 직접적인 해결 방법은 없습니다. 구체적인 클래스로 역 직렬화 할 수 있어야합니다. 할 수없는 경우 옵션은 수동으로 (위) 구성, JSONGenerator 사용 또는 일반 개체 사용 (예 :)과 같은 것 List<Map<String, Object>>
입니다.
중요한 업데이트 활성화로 인해 오늘이 문제가 발생했습니다. 추상 클래스를 가상 클래스로 변경하여 해결할 수있었습니다.