ไม่สามารถ deserialize JSON เป็นชนิดนามธรรม
เมื่อเรียกใช้การทดสอบที่ deserializing สตริง JSON ฉันได้รับข้อความแสดงข้อผิดพลาด:
ไม่สามารถ deserialize JSON เป็นชนิดนามธรรม: TestController.Iem
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 ที่มีข้อผิดพลาดเดียวกัน มีการอัปเดตที่สำคัญและฉันแน่ใจว่านี่เป็นสาเหตุของปัญหา
คุณมีความคิดที่จะแก้ปัญหานั้นหรือไม่?
คำตอบ
แม้ว่าโค้ดนี้จะคอมไพล์และรัน แต่ก็มีปัญหา คุณไม่สามารถสร้างอินสแตนซ์ SomeItem ภายในรายการไอเท็มได้จริงเนื่องจากตัวแยกวิเคราะห์ JSON ไม่ทราบว่าคุณหมายถึงการใช้ประเภทย่อยใด
ด้วยเหตุนี้การอัปเดตที่สำคัญจึงเป็นสิ่งที่ดีเพราะจะแก้ไขพฤติกรรมที่ผิดปกติด้วยรหัสประเภทนี้ วิธีแก้ปัญหาคือการสร้างวัตถุในหน่วยความจำด้วยตนเอง
นอกจากนี้ยังชี้ให้เห็นถึงข้อบกพร่องในการออกแบบที่เป็นไปได้หากต้องการใช้กับ API บางประเภทที่จะใช้ JSON มันใช้งานไม่ได้เพราะระบบไม่สามารถระบุประเภทของคลาสย่อยที่ถูกต้องที่จะใช้สำหรับประเภทข้อมูลได้และในภาษาที่พิมพ์อย่างรุนแรงเช่น Apex นั่นเป็นปัญหา
เนื่องจากทุกอย่างถูกทำเครื่องหมายเป็น TestVisible วิธีแก้ไขที่ถูกต้องคือการสร้างวัตถุด้วยตนเอง
TestController.SomeClass wrapper = new TestController.SomeClass();
wrapper.items = new TestController.SomeItem[0];
wrapper.items.add(new TestController.SomeItem());
// etc //
โดยสรุปไม่มีวิธีแก้ปัญหาโดยตรง คุณต้องสามารถ deserialize เป็นคลาสที่เป็นรูปธรรมได้ หากคุณทำไม่ได้ตัวเลือกของคุณจะเป็นเช่นการสร้างด้วยตนเอง (ด้านบน) โดยใช้ JSONGenerator หรือใช้วัตถุทั่วไป (เช่นList<Map<String, Object>>
)
ฉันพบปัญหานี้ในวันนี้เนื่องจากการเปิดใช้งานการอัปเดตที่สำคัญ ฉันสามารถแก้ไขได้โดยเปลี่ยนคลาสนามธรรมเป็นคลาสเสมือน