Closed cropredyHelix closed 3 years ago
Attempting to set a field or relationship that does not exist will now result in an exception.
That is, the decision was to ensure that case sensitivity is enforced.
Having tested with the following:
Order[] mockOrders= new List<Order>{
(Order) new sfab_FabricatedSobject( Order.class )
.setField( Order.Id, 'OrderId' )
.setField( Order.BilltoContactId, 'ContactId' )
.setParent( 'BilltoContact', new sfab_FabricatedSObject( Contact.class ) ) // the suspect line
.setField( Contact.Email, 'foo@bar.com' )
.toSObject()
};
The result is now:
sfab_FabricatedSObject.ParentRelationshipDoesNotExistException: The parent relationship Order.BilltoContact does not exist
Note, in correcting the above reference, the code now becomes:
Order[] mockOrders= new List<Order>{
(Order) new sfab_FabricatedSobject( Order.class )
.setField( Order.Id, 'OrderId' )
.setField( Order.BilltoContactId, 'ContactId' )
.setParent( 'BillToContact', new sfab_FabricatedSObject( Contact.class ) ) // the suspect line
.setField( Contact.Email, 'foo@bar.com' )
.toSObject()
};
This code now throws the following exception:
sfab_FabricatedSObject.FieldDoesNotExistException: The field Order.Email does not exist
This is because it is not possible to traverse a parent relationship when using SObjectField references in this way. I.E. there is no reference within the SObjectField to the object in which the Email field exists. It is not possible for Sobject Fabricator to see that the Contact has been referenced here and attach it to the correct object (incidentally, there is no correct relationship in any case). Hopefully this is now more apparent when this mistake has been made.
Note that the documentation has been updated highlight this limitation
@bobalicious
I think you might have read my example incorrectly (or I am misinterpreting your response)
(Order) new sfab_FabricatedSobject( Order.class )
.setField( Order.Id, 'OrderId' )
.setField( Order.BilltoContactId, 'ContactId' )
.setParent( 'BillToContact', new sfab_FabricatedSObject( Contact.class ) // the corrected line
.setField( Contact.Email, 'foo@bar.com' )) // parent Contact Email
.toSObject()
};
unless you were trying to say that something like this now throws exception sfab_FabricatedSObject.FieldDoesNotExistException: The field Order.Email does not exist
Order[] mockOrders= new List<Order>{
(Order) new sfab_FabricatedSobject( Order.class )
.setField( Order.Id, 'OrderId' )
.setField( Contact.Email, 'foo@bar.com' ) // oops, wrong SObjectType
.toSObject()
};
That is correct. The last piece code as posted now throws an exception because there is no Email field on Order.
51.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO
Execute Anonymous: Order[] mockOrders= new List<Order>{
Execute Anonymous: (Order) new sfab_FabricatedSobject( Order.class )
Execute Anonymous: .setField( Order.Id, 'OrderId' )
Execute Anonymous: .setField( Contact.Email, 'foo@bar.com' ) // oops, wrong SObjectType
Execute Anonymous: .toSObject()
Execute Anonymous: };
19:32:14.60 (60110619)|USER_INFO|[EXTERNAL]|00525000006yUme|xxxxxxxxxxx@example.com|(GMT+00:00) Greenwich Mean Time (Europe/London)|GMTZ
19:32:14.60 (60137497)|EXECUTION_STARTED
19:32:14.60 (60152730)|CODE_UNIT_STARTED|[EXTERNAL]|execute_anonymous_apex
19:32:14.60 (184920066)|EXCEPTION_THROWN|[362]|sfab_FabricatedSObject.FieldDoesNotExistException: The field Order.Email does not exist
19:32:14.60 (184970667)|EXCEPTION_THROWN|[4]|sfab_FabricatedSObject.FieldDoesNotExistException: The field Order.Email does not exist
19:32:14.60 (185417787)|FATAL_ERROR|sfab_FabricatedSObject.FieldDoesNotExistException: The field Order.Email does not exist
Apologies - I appear to have incorrectly moved a bracket when trying to get your example to compile.
A more accurate representation of your example, working, is:
Order[] mockOrders = new list<Order>{
(Order) new sfab_FabricatedSobject(Order.class)
.setField(Order.Id, 'id-1')
.setField(Order.BilltoContactId, 'id-2' )
.setParent('BillToContact',new sfab_FabricatedSObject(Contact.class)
.setField(Contact.Email,'foo@bar.com')
)
.toSobject()
};
This does work.
This took me a couple of perplexing hours to figure out today
So, inspect the parent relationship sobject BillToContact for the mockOrder[0] and ...
The issue is that the actual relationship name is
BillToContact
, notBilltoContact
. As you serialize/deserialize, SFDC appears to ignore relationship names that aren't perfect match, case-wise! Although Apex is not case sensitive on SFDC object, field, or relationship names; the serialize/deserialize approach appears to be not so tolerant.The user fix is:
I'm not sure exactly what the right fix is:
setParent
orsetChildren
relationship name doesn't exist