### Example of Custom Test Data Builder Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md This markdown example demonstrates how to document custom test data builders that utilize SObjectFabricator within your project's README file. It shows a sample Apex code snippet. ```markdown ## Test Data Builders Uses SObjectFabricator for test data creation. Example: ```apex Account account = (Account)TestDataBuilder.createAccount('ACME').toSObject(); ``` See `/classes/TestDataBuilder.cls` for implementation. ``` -------------------------------- ### Install Managed Package with SFDX Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Install a managed package into a target org using its PackageVersionId. The '-w 10' flag waits up to 10 minutes for installation. ```bash sfdx force:package:install --package=[PackageVersionId] -w 10 -u target-org ``` -------------------------------- ### Example: Post-Build Process during toSObject() Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ParentRelationshipNode.md Illustrates the postBuildProcess execution flow during the toSObject() operation, highlighting how parent relationships and Blob fields are handled. ```apex // Processing: // 1. Serialize: Creates Map with Contact fields and { 'Account': { 'Id': 'CustomId', ... } } // 2. Deserialize: Contact JSON → Contact SObject, Account JSON → Account SObject // 3. postBuildProcess(contact): // - For Account ParentRelationshipNode: // - Retrieve Account from contact: contact.getSobject('Account') // - Call parent.postBuildProcess(accountRecord) // - Applies Blob fields to accountRecord ``` -------------------------------- ### Fluent API for Account SObject Configuration Source: https://github.com/mattaddy/sobjectfabricator/blob/master/readme.md Shows how to chain multiple `set` and `add` method calls to configure an Account SObject in a fluent, readable style. This consolidates the setup process into a single chain of operations. ```java Account sObjectAccount = (Account)new sfab_FabricatedSObject( Account.class ) .set( Account.Id, 'Id-1' ) .set( Account.LastModifiedDate, Date.newInstance( 2017, 1, 1 ) ) .set( 'Name', 'The Account Name' ) .set( 'Owner', new sfab_FabricatedSObject( User.class ).set( 'Username', 'TheOwner' ) ) .set( 'Opportunities', new List { new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-1' ), new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-2' ) }) .add( 'Opportunities', new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-3' ) ) // though, it would be odd to combine set .add( 'Opportunities', new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-4' ) ) // and add on a single child relationship .toSObject(); ``` -------------------------------- ### Database-Backed Test (Before) Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md This is an example of a traditional database-backed Apex test. It involves creating and inserting records into the database, which can be slower and more complex. ```apex @isTest static void testAccountProcessing() { // Create test data in database Account account = new Account(Name = 'Test'); insert account; Contact contact = new Contact(LastName = 'Test', AccountId = account.Id); insert contact; // Test logic List contacts = [SELECT Id FROM Contact WHERE AccountId = :account.Id]; System.assertEquals(1, contacts.size()); } ``` -------------------------------- ### Example: Serializing a Parent Relationship Node Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ParentRelationshipNode.md Demonstrates how a sfab_ParentRelationshipNode serializes a parent SObject into a Map format, showing the expected output structure. ```apex // Given: sfab_FabricatedSObject parent = new sfab_FabricatedSObject(Account.class) .set('Name', 'Parent') .set('Id', 'AcctId1'); sfab_ParentRelationshipNode node = new sfab_ParentRelationshipNode('Account', parent); // Serializes to: // { // 'Account': { // 'Name': 'Parent', // 'Id': 'AcctId1' // } // } ``` -------------------------------- ### Create FabricatedSObject Instance Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Instantiates a new sfab_FabricatedSObject for a given SObject type. Use this as a starting point for further configuration. ```apex sfab_FabricatedSObject fabricatedAccount = new sfab_FabricatedSObject(Account.class); ``` -------------------------------- ### Reference SObjectFabricator Classes in a Namespace Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md When using SObjectFabricator in an org with a namespace, prefix the class names with your namespace. This example shows how to instantiate a fabricated Account object. ```apex // Reference becomes: [YourNamespace].sfab_FabricatedSObject // Example: Account account = (Account)new [YourNamespace].sfab_FabricatedSObject(Account.class) .set('Name', 'Test') .toSObject(); ``` -------------------------------- ### Instantiate and Use sfab_FabricatedSObject in Apex Test Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Example of how to instantiate the main SObjectFabricator class and use its methods within an Apex test class. No explicit imports are needed as it uses fully-qualified names. ```apex // Example test class using SObjectFabricator @isTest private class MyTestClass { @isTest static void testSomething() { // Use SObjectFabricator Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Test Account') .toSObject(); System.assertEquals('Test Account', account.Name); } } ``` -------------------------------- ### Handle FieldDoesNotExistException Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/README.md Example of how to catch a FieldDoesNotExistException when attempting to set a field that does not exist on the SObject. This ensures robust error handling in your code. ```apex try { account.toSObject(); } catch (sfab_FabricatedSObject.FieldDoesNotExistException e) { System.debug('Error: ' + e.getMessage()); } ``` -------------------------------- ### Catching ChildRelationshipDoesNotExistException Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/errors.md This example shows how to catch errors when a specified child relationship does not exist. This is relevant when using methods like `add` to add child records. ```apex try { new sfab_FabricatedSObject(Account.class) .add('NonExistentChildren', new sfab_FabricatedSObject(Contact.class)) .toSObject(); } catch (sfab_FabricatedSObject.ChildRelationshipDoesNotExistException e) { System.debug('Caught: ' + e.getMessage()); } ``` -------------------------------- ### Setting Parent Relationships on a Contact SObject Source: https://github.com/mattaddy/sobjectfabricator/blob/master/readme.md Illustrates how to set fields on a Contact SObject that involve parent relationships, such as Account.Name, Account.Owner, and Account.Opportunities. This example demonstrates setting child relationships on a parent object implicitly. ```java sfab_FabricatedSObject fabricatedContact = new sfab_FabricatedSObject( Contact.class ); fabricatedContact.set( 'Account.Name', 'The Account Name' ); fabricatedContact.set( 'Account.Owner', new sfab_FabricatedSObject( User.class ) ); fabricatedContact.set( 'Account.Opportunities', new List { new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-1' ), new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-2' ) }); fabricatedContact.add( 'Account.Opportunities', new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-1' ) ); Contact sObjectContact = (Contact)fabricatedContact.toSObject(); ``` -------------------------------- ### Fabricator-Based Test (After Migration) Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md This snippet shows the migrated version of the previous test, using SObject Fabricator for in-memory data creation. This approach offers significant performance benefits and simplifies test setup. ```apex @isTest static void testAccountProcessing() { // Create test data in-memory Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Test') .add('Contacts', new sfab_FabricatedSObject(Contact.class).set('LastName', 'Test')) .toSObject(); // Test logic System.assertEquals(1, account.Contacts.size()); } ``` -------------------------------- ### Deploy to Sandbox and Run Tests Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Best practice is to first deploy and test SObjectFabricator in a sandbox environment before deploying to production. Replace 'sandbox-alias' with your sandbox's alias. ```bash sfdx force:source:push -u sandbox-alias sfdx force:apex:test:run -u sandbox-alias ``` -------------------------------- ### ChildRelationshipNode Methods Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObjectNode.md Provides methods to add children, get the relationship name, and retrieve the list of children. ```apex public sfab_ChildRelationshipNode addChild(sfab_FabricatedSObject child) ``` ```apex public String getName() ``` ```apex public Integer getNumberOfChildren() ``` ```apex public List getChildren() ``` -------------------------------- ### Create a Simple Account Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Demonstrates the basic usage of SObjectFabricator to create a simple Account record with a specified name. ```apex // Create a simple Account Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Test Account') .toSObject(); ``` -------------------------------- ### ParentRelationshipNode Methods Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObjectNode.md Provides methods to get the parent object and to set fields or add children to the parent. ```apex public sfab_FabricatedSObject getParent() ``` ```apex public sfab_FabricatedSObject set(String fieldName, Object value) ``` ```apex public sfab_FabricatedSObject add(String fieldName, sfab_FabricatedSObject fabricatedChild) ``` -------------------------------- ### Get Child Relationship Name Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ChildRelationshipNode.md Retrieves the configured name of the child relationship. This is the field name used during instantiation. ```apex public String getName() ``` ```apex sfab_ChildRelationshipNode node = new sfab_ChildRelationshipNode('Opportunities'); String relationshipName = node.getName(); // Returns 'Opportunities' ``` -------------------------------- ### Cloning and Modifying SObjects Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Demonstrates how to achieve a cloning-like behavior by creating a base configuration and then instantiating and modifying new SObjects based on that configuration. This is useful for generating multiple similar records with slight variations. ```apex // Create base configuration sfab_FabricatedSObject baseConfig = new sfab_FabricatedSObject(Account.class) .set('Name', 'Base Account') .set('Industry', 'Technology'); // Reuse and modify for multiple instances Account account1 = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Account 1') .set('Industry', 'Technology') .toSObject(); Account account2 = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Account 2') .set('Industry', 'Technology') .toSObject(); ``` -------------------------------- ### Create and Push to Scratch Org with SFDX Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Commands to create a new Salesforce DX scratch org and push your source code to it. Ensure your project-scratch-def.json is configured. ```bash sfdx force:org:create -s -f config/project-scratch-def.json ``` ```bash sfdx force:source:push ``` ```bash sfdx force:source:pull ``` -------------------------------- ### Get SObject Field Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ObjectDescriber.md Retrieves the Schema.SObjectField for a specified object and field name. Returns null if the field does not exist. ```Apex public SobjectField getField(String objectName, String fieldName) ``` ```Apex sfab_ObjectDescriber describer = new sfab_ObjectDescriber(); Schema.SObjectField nameField = describer.getField('Account', 'Name'); ``` -------------------------------- ### Clone Repository and Create Branch Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Use Git to clone the SObjectFabricator repository, create a new branch for your customizations, commit changes, and push them to your remote repository. ```bash git clone https://github.com/mattaddy/SObjectFabricator.git your-project git branch your-customizations git commit -a -m "Custom changes" git push origin your-customizations ``` -------------------------------- ### Build Account with Initial Children Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ChildRelationshipNode.md Constructs an Account SObject and sets its 'Opportunities' child relationship with a list of SObjects during initialization. This is a common pattern for setting up parent-child relationships. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Parent Account') .set('Opportunities', new List { new sfab_FabricatedSObject(Opportunity.class).set('Name', 'Opp1'), new sfab_FabricatedSObject(Opportunity.class).set('Name', 'Opp2') }) .toSObject(); ``` -------------------------------- ### Get Field Value from Node Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FieldValuePairNode.md Retrieves the configured value for the field represented by this node. Use this to inspect the assigned value. ```apex public Object getValue() ``` ```apex sfab_FieldValuePairNode node = new sfab_FieldValuePairNode(Account.Name, 'Test Account'); Object value = node.getValue(); // Returns 'Test Account' ``` -------------------------------- ### Simple SObject Creation Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Instantiate a fabricated SObject and configure its fields later. Use this for basic object creation where all fields are set after initialization. ```apex sfab_FabricatedSObject fab = new sfab_FabricatedSObject(Account.class); // Configure later fab.set('Name', 'Test'); Account account = (Account)fab.toSObject(); ``` -------------------------------- ### Get Field Name from Node Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FieldValuePairNode.md Retrieves the name of the SObject field associated with this node. Useful for dynamic field access. ```apex public String getName() ``` ```apex sfab_FieldValuePairNode node = new sfab_FieldValuePairNode(Account.Name, 'Test'); String fieldName = node.getName(); // Returns 'Name' ``` -------------------------------- ### Create a Simple Account Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/README.md Use the sfab_FabricatedSObject constructor with the SObject class and the set() method to define field values. The toSObject() method returns the fabricated SObject. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Test Account') .toSObject(); System.debug(account.Name); // Test Account ``` -------------------------------- ### Fabricate SObject and Set Fields Source: https://github.com/mattaddy/sobjectfabricator/blob/master/readme.md Create an SObject instance and set its field values. Use this for basic SObject creation and field population in tests. ```java Account accountSobject = (Account)new sfab_FabricatedSObject( Account.class ) .set( 'Name' , 'Account Name' ) .set( 'LastModifiedDate', Date.newInstance( 2017, 1, 1 ) ) .toSObject(); ``` -------------------------------- ### Get Node Name Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObjectNode.md Returns the name of the field or relationship represented by the node. This is used internally to identify the node's target. ```apex String getName() ``` -------------------------------- ### Fabricating and Configuring an Account SObject Source: https://github.com/mattaddy/sobjectfabricator/blob/master/readme.md Demonstrates setting various fields on an Account SObject, including Id, LastModifiedDate, Name, and relationships like Owner and Opportunities. It shows how to set relationships explicitly, implicitly via field names, and for multi-level relationships. Finally, it converts the fabricated object to a standard SObject. ```java sfab_FabricatedSObject fabricatedAccount = new sfab_FabricatedSObject( Account.class ); // Set fields using SObjectField references, including those not normally settable: fabricatedAccount.set( Account.Id, 'Id-1' ); fabricatedAccount.set( Account.LastModifiedDate, Date.newInstance( 2017, 1, 1 ) ); // Set fields using the names of the fields: fabricatedAccount.set( 'Name', 'The Account Name' ); // Set lookup / master detail relationships explicitly fabricatedAccount.set( 'Owner', new sfab_FabricatedSObject( User.class ).set( 'Username', 'TheOwner' ) ); // Set lookup / master detail relationships implicitly fabricatedAccount.set( 'Owner.Alias', 'alias' ); // Set multi-leveled lookup / master detail relationships implicitly fabricatedAccount.set( 'Owner.Profile.Name', 'System Administrator' ); // Set child relationships in one go fabricatedAccount.set( 'Opportunities', new List { new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-1' ), new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-2' ) }); // Set child relationships one-by-one fabricatedAccount.add( 'Opportunities', new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-3' ) ); fabricatedAccount.add( 'Opportunities', new sfab_FabricatedSObject( Opportunity.class ).set( 'Id', 'OppId-4' ) ); // Generate an SObject from that configuration Account sObjectAccount = (Account)fabricatedAccount.toSObject(); // Account:{LastModifiedDate=2017-01-01 00:00:00, Id=Id-1, Name=The Account Name} System.debug( sObjectAccount ); // User:{Username=TheOwner, Alias=alias} System.debug( sObjectAccount.Owner ); // Profile:{Name=System Administrator} System.debug( sObjectAccount.Owner.Profile ); // (Opportunity:{Id=OppId-1}, Opportunity:{Id=OppId-2}, Opportunity:{Id=OppId-3}, Opportunity:{Id=OppId-4}) System.debug( sObjectAccount.Opportunities ); ``` -------------------------------- ### Get All Children Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ChildRelationshipNode.md Retrieves the complete list of fabricated SObjects currently associated with this child relationship. Returns an empty list if no children have been added. ```apex public List getChildren() ``` ```apex sfab_ChildRelationshipNode node = new sfab_ChildRelationshipNode('Opportunities', childList); List children = node.getChildren(); ``` -------------------------------- ### Deploy All Classes with SFDX CLI Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Use this command to deploy all Apex classes from the force-app directory to your target Salesforce org. ```bash sfdx force:source:deploy -p force-app --targetusername your-org-alias ``` -------------------------------- ### Get Number of Children Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ChildRelationshipNode.md Returns the current count of child SObjects associated with this relationship node. Useful for checking the size of the child collection. ```apex public Integer getNumberOfChildren() ``` ```apex sfab_ChildRelationshipNode node = new sfab_ChildRelationshipNode('Opportunities') .addChild(new sfab_FabricatedSObject(Opportunity.class)) .addChild(new sfab_FabricatedSObject(Opportunity.class)); Integer count = node.getNumberOfChildren(); // Returns 2 ``` -------------------------------- ### Bulk Setting Account Fields via Map Source: https://github.com/mattaddy/sobjectfabricator/blob/master/readme.md Demonstrates setting Account SObject fields in bulk using a `Map`. This can be done either during the construction of the fabricated object or by using the `set` method with the map. ```java Map accountValues = new Map { Account.Id => 'Id-1', Account.LastModifiedDate => Date.newInstance(2017, 1, 1) }; Account fabricatedViaConstructor = (Account)new sfab_FabricatedSObject(Account.class, accountValues) .toSObject(); Account fabricatedViaSet = (Account)new sfab_FabricatedSObject(Account.class) .set(accountValues) .toSObject(); ``` -------------------------------- ### Set Simple Fields Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Illustrates setting various simple field types on an Account object, including text, picklist, system, and date fields. ```apex new sfab_FabricatedSObject(Account.class) .set('Name', 'Test') .set('Industry', 'Technology') .set(Account.Id, 'CustomId123') // Can set system fields .set(Account.LastModifiedDate, DateTime.now()) .toSObject(); ``` -------------------------------- ### Catching FieldIsNotSimpleFieldException Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/errors.md This example demonstrates how to catch errors when trying to assign a primitive value to a field that is a relationship (parent or child). This exception is thrown by `setDirectField`. ```apex try { new sfab_FabricatedSObject(Contact.class) .set('Account', 'InvalidValue') // Account is a relationship .toSObject(); } catch (sfab_FabricatedSObject.FieldIsNotSimpleFieldException e) { System.debug('Caught: ' + e.getMessage()); // Cannot set to a primitive, it is a parent relationship field } ``` -------------------------------- ### Deploy SObjectFabricator using SFDX Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/README.md Quickly deploy SObjectFabricator to your Salesforce org using the SFDX CLI. Ensure you have the 'force-app' directory correctly configured. ```bash sfdx force:source:deploy -p force-app -u your-org-alias ``` -------------------------------- ### Get SObject Name Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Returns the String name of the SObject type being fabricated. Use this to retrieve the API name of the SObject that the fabricator is configured to build. ```apex public String getSobjectName() ``` ```apex sfab_FabricatedSObject fab = new sfab_FabricatedSObject(Account.class); String typeName = fab.getSobjectName(); // Returns 'Account' ``` -------------------------------- ### Basic Field Setting Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Demonstrates the basic usage of setting simple field values on an SObject fabricator. Use the `set` method to assign values to fields before converting to an SObject. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'My Account') .set('Industry', 'Technology') .toSObject(); ``` -------------------------------- ### SObjectField Key Methods Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/types.md Highlights essential methods for interacting with SObjectField, used to reference individual fields on SObjects. ```apex Schema.DescribeFieldResult getDescribe() String getName() ``` -------------------------------- ### Document Complex Object Hierarchies Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Use the fluent API to clearly define and build complex, nested object structures. This improves readability and maintainability of test data setup. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Parent Account') // Contact under account .add('Contacts', new sfab_FabricatedSObject(Contact.class) .set('FirstName', 'John') .set('LastName', 'Doe') // Contact's owner user .set('Owner.Alias', 'jdoe')) // Opportunity under account .add('Opportunities', new sfab_FabricatedSObject(Opportunity.class) .set('Name', 'Large Deal') .set('Amount', 100000)) .toSObject(); ``` -------------------------------- ### Get Valid Parent Object Types for Relationship Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ObjectDescriber.md Retrieves a sorted list of SObject type names that are valid for a given parent relationship. Returns an empty list if the relationship does not exist. ```Apex public List getObjectTypesForParentRelationship(String objectName, String relationshipName) ``` ```Apex sfab_ObjectDescriber describer = new sfab_ObjectDescriber(); List validTypes = describer.getObjectTypesForParentRelationship('Contact', 'Account'); // Returns List of valid parent types (e.g., 'Account') ``` -------------------------------- ### Set System Fields on Account Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Demonstrates setting system fields like Id, CreatedDate, and LastModifiedDate on an Account object, which is a key capability of SObjectFabricator. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set(Account.Id, 'CustomId123') .set(Account.CreatedDate, DateTime.newInstance(2020, 1, 1)) .set(Account.LastModifiedDate, DateTime.newInstance(2024, 1, 1)) .toSObject(); System.debug(account.Id); // CustomId123 System.debug(account.CreatedDate); // 2020-01-01 00:00:00 ``` -------------------------------- ### SObject Creation with String Field Map Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Create a fabricated SObject and initialize its fields using a String to Object map. This is convenient for setting fields, including relationship fields, using their string names. ```apex Contact contact = (Contact)new sfab_FabricatedSObject(Contact.class, new Map { 'FirstName' => 'John', 'LastName' => 'Doe', 'Account.Name' => 'ACME Corp' }).toSObject(); ``` -------------------------------- ### SObject Creation with Field Map Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Create a fabricated SObject and initialize its fields using an SObjectField to Object map. This is useful when you have the field API names available. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class, new Map { Account.Name => 'Test Account', Account.Industry => 'Technology' }).toSObject(); ``` -------------------------------- ### Retrieve Child Object Type for Relationship Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ObjectDescriber.md Use this method to get the SObject type name of child records associated with a specific parent SObject and child relationship. Returns null if the relationship doesn't exist. ```apex public String getObjectTypeForChildRelationship(String objectName, String relationshipName) ``` ```apex sfab_ObjectDescriber describer = new sfab_ObjectDescriber(); String childType = describer.getObjectTypeForChildRelationship('Account', 'Opportunities'); // Returns 'Opportunity' ``` -------------------------------- ### Deploy Production Classes with SFDX CLI Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md This command deploys only Apex classes, excluding test classes, to your target org. Ensure your org alias is correctly specified. ```bash sfdx force:source:deploy -p force-app --includetype ApexClass --targetusername your-org-alias ``` -------------------------------- ### Constructors Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ChildRelationshipNode.md Information on how to instantiate sfab_ChildRelationshipNode. ```APIDOC ## sfab_ChildRelationshipNode(String fieldName) ### Description Creates an empty child relationship node. ### Method `sfab_ChildRelationshipNode(String fieldName)` ### Parameters #### Path Parameters - **fieldName** (String) - Required - The relationship name (e.g., 'Opportunities', 'Contacts') ### Request Example ```apex sfab_ChildRelationshipNode node = new sfab_ChildRelationshipNode('Opportunities'); ``` --- ## sfab_ChildRelationshipNode(String fieldName, List children) ### Description Creates a child relationship node with initial child objects. ### Method `sfab_ChildRelationshipNode(String fieldName, List children)` ### Parameters #### Path Parameters - **fieldName** (String) - Required - The relationship name - **children** (List) - Required - Initial list of child objects ### Request Example ```apex List children = new List { new sfab_FabricatedSObject(Opportunity.class).set('Id', 'Opp1'), new sfab_FabricatedSObject(Opportunity.class).set('Id', 'Opp2') }; sfab_ChildRelationshipNode node = new sfab_ChildRelationshipNode('Opportunities', children); ``` ``` -------------------------------- ### Run All Apex Tests with SFDX CLI Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Execute all Apex tests in your target org using the SFDX CLI. Replace 'your-org-alias' with your actual org alias. ```bash sfdx force:apex:test:run -u your-org-alias ``` -------------------------------- ### Convert to SObject Instance Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Builds and returns the SObject instance represented by this fabricator. This method serializes the fabricated configuration, converts it to JSON, and then deserializes it back to the target SObject type, handling Blob fields. ```apex public SObject toSObject() ``` ```apex Account accountSObject = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Account Name') .set('Owner', new sfab_FabricatedSObject(User.class).set('Username', 'TheOwner')) .toSObject(); ``` -------------------------------- ### System and Formula Fields Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Shows how to set system fields (like Id and LastModifiedDate) and formula fields using their API names or Schema references. This allows for precise control over system-managed or calculated fields. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set(Account.Id, 'CustomId123') .set(Account.LastModifiedDate, DateTime.now()) .set('Name', 'My Account') .toSObject(); ``` -------------------------------- ### Push Source to Production Org Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Deploy source code from your local machine to a different target Salesforce org, such as a production org. Specify the target org alias. ```bash sfdx force:source:push -u production-org-alias ``` -------------------------------- ### Build Account by Adding Children Incrementally Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ChildRelationshipNode.md Constructs an Account SObject and adds child Opportunities one by one using the .add() method. This pattern is useful for dynamically building child relationships. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Parent Account') .add('Opportunities', new sfab_FabricatedSObject(Opportunity.class).set('Name', 'Opp1')) .add('Opportunities', new sfab_FabricatedSObject(Opportunity.class).set('Name', 'Opp2')) .toSObject(); ``` -------------------------------- ### Pull Source from Scratch Org Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Retrieve source code from a Salesforce DX scratch org to your local machine. Specify the scratch org alias. ```bash sfdx force:source:pull -u scratch-org-alias ``` -------------------------------- ### Fluent Construction with Nested Relationships Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Illustrates fluent construction of SObjects with multiple levels of nested relationships, including setting fields on parent, child, and grandchild objects. ```Apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set(Account.Id, 'AcctId1') .set('Name', 'ACME Corp') .set('Owner', new sfab_FabricatedSObject(User.class) .set('Username', 'user@example.com') .set('Alias', 'usa')) .add('Contacts', new sfab_FabricatedSObject(Contact.class) .set('LastName', 'Smith') .set('FirstName', 'John')) .toSObject(); ``` -------------------------------- ### Pull Latest Changes and Deploy Updates Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Update your local repository to the latest version from the main branch and then deploy the changes to your org using the Salesforce CLI. ```bash # Pull latest from main branch git fetch origin git pull origin main # Deploy updates sfdx force:source:push -u your-org-alias ``` -------------------------------- ### Configure Parent Objects using Dot Notation Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ParentRelationshipNode.md Demonstrates configuring nested parent objects using dot notation, which internally utilizes sfab_ParentRelationshipNode for delegation. ```apex sfab_FabricatedSObject contact = new sfab_FabricatedSObject(Contact.class) .set('Account.Name', 'Parent Account') .set('Account.Owner.Username', 'owner'); ``` -------------------------------- ### Create Test Account with Custom Utility Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Utilize this custom utility class to create test Accounts with a specified number of associated Contacts. This simplifies the creation of complex test data structures. ```apex public class TestUtils { public static Account createTestAccount(String name, Integer contactCount) { sfab_FabricatedSObject fab = new sfab_FabricatedSObject(Account.class) .set('Name', name); for (Integer i = 0; i < contactCount; i++) { fab.add('Contacts', new sfab_FabricatedSObject(Contact.class) .set('LastName', 'Contact ' + i)); } return (Account)fab.toSObject(); } } ``` -------------------------------- ### Convert Source to MDAPI Format Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Convert your Salesforce DX source code to the Metadata API format for deployment using Change Sets or the Ant Migration Tool. The output will be in the mdapi_output directory. ```bash sfdx force:source:convert -r force-app -d mdapi_output ``` -------------------------------- ### DescribeSObjectResult Key Methods Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/types.md Presents core methods of DescribeSObjectResult, used to retrieve metadata for an SObject type. ```apex Map fields.getMap() List getChildRelationships() String getName() ``` -------------------------------- ### Test with Mock Objects Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md This snippet demonstrates using fabricated SObjects with mocked services for testing. It allows testing business logic without actual database interactions. ```apex @isTest static void testWithMocks() { // Create fabricated test data Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Test') .toSObject(); // Use with mocked services AccountService service = new AccountService(); service.processAccount(account); // Service doesn't query DB } ``` -------------------------------- ### Configure Parent Objects Directly Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ParentRelationshipNode.md Shows the direct approach to configuring parent SObjects using sfab_FabricatedSObject's set() method without explicitly using ParentRelationshipNode. ```apex sfab_FabricatedSObject parentAccount = new sfab_FabricatedSObject(Account.class) .set('Name', 'Parent Account') .set('Owner', new sfab_FabricatedSObject(User.class).set('Username', 'owner')); sfab_FabricatedSObject contact = new sfab_FabricatedSObject(Contact.class) .set('Account', parentAccount); ``` -------------------------------- ### Set Account Fields using SObjectField References Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Uses SObjectField references for setting Account fields, providing compile-time checking and IDE support. This method is preferred for refactoring safety. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set(Account.Name, 'Test Account') .set(Account.BillingCity, 'San Francisco') .toSObject(); ``` -------------------------------- ### Build Complex Object Graph Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/README.md Demonstrates how to construct a complex object graph with nested relationships, including accounts, contacts, opportunities, and line items. This pattern is useful for setting up intricate test scenarios. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Parent Account') .add('Contacts', new sfab_FabricatedSObject(Contact.class) .set('FirstName', 'John') .set('LastName', 'Doe')) .add('Opportunities', new sfab_FabricatedSObject(Opportunity.class) .set('Name', 'Large Deal') .set('Amount', 100000) .add('OpportunityLineItems', new sfab_FabricatedSObject(OpportunityLineItem.class) .set('Quantity', 10))) .toSObject(); ``` -------------------------------- ### Constructor(Type, Map) Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Creates a FabricatedSObject and initializes it with field values using SObjectField references. This constructor allows for pre-populating the SObject with specific fields and their values. ```APIDOC ## Constructor(Type, Map) ### Description Creates a FabricatedSObject and initializes it with field values using SObjectField references. ### Method Constructor ### Parameters #### Path Parameters - **sType** (Type) - Required - The SObject type to fabricate - **fields** (Map) - Required - Map of SObjectField references to values to set ### Request Example ```apex Map accountValues = new Map { Account.Id => 'Id-1', Account.LastModifiedDate => Date.newInstance(2017, 1, 1) }; Account fabricatedAccount = (Account)new sfab_FabricatedSObject(Account.class, accountValues).toSObject(); ``` ### Response #### Success Response - **sfab_FabricatedSObject instance with fields initialized** - The newly created sfab_FabricatedSObject instance with fields initialized. ``` -------------------------------- ### Run Specific Apex Tests with SFDX CLI Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md Run a specific set of Apex tests by providing their names. This is useful for targeted testing after deployments. Use '-r human' for human-readable output. ```bash sfdx force:apex:test:run -n sfab_FabricatedSObjectTest,sfab_FieldValuePairNodeTest -u your-org-alias ``` ```bash sfdx force:apex:test:run -u your-org-alias -r human ``` -------------------------------- ### Set Multiple Simple Fields in Bulk Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Use this method to efficiently set multiple simple fields at once using a map of SObjectField references to their corresponding values. This is a convenient way to populate several fields simultaneously. ```apex public sfab_FabricatedSObject set(Map fields) ``` ```apex sfab_FabricatedSObject fabricatedAccount = new sfab_FabricatedSObject(Account.class) .set(new Map { Account.Id => 'Id-1', Account.Name => 'Account Name' }); ``` -------------------------------- ### Configure Namespace in sfdx-project.json Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/deployment.md If your org has a namespace, ensure it is correctly specified in the 'namespace' field within your 'sfdx-project.json' file. This is crucial for package deployment. ```json { "packageDirectories": [ { "path": "force-app", "default": true } ], "namespace": "your_namespace", "name": "your-package-name" } ``` -------------------------------- ### Account Factory Pattern Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/README.md Implements the Factory pattern for creating Account objects, allowing for fluent configuration of fields. Use this for a more object-oriented approach to object creation. ```apex public class AccountFactory extends SObjectFactory { public AccountFactory() { super(Account.class); } public AccountFactory withName(String name) { fab.set('Name', name); return this; } } // Usage Account account = (Account)new AccountFactory() .withName('Test') .build(); ``` -------------------------------- ### Create sfab_ChildRelationshipNode with Initial Children Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_ChildRelationshipNode.md Instantiates a child relationship node with a predefined list of child objects. Useful for initializing with existing data. ```apex public sfab_ChildRelationshipNode(String fieldName, List children) ``` ```apex List children = new List { new sfab_FabricatedSObject(Opportunity.class).set('Id', 'Opp1'), new sfab_FabricatedSObject(Opportunity.class).set('Id', 'Opp2') }; sfab_ChildRelationshipNode node = new sfab_ChildRelationshipNode('Opportunities', children); ``` -------------------------------- ### Set Formula Field on Account Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Shows how to set a formula field on an Account object. This capability allows for simulating calculated fields during testing. ```apex // If Account had a formula field "AnnualRevenueFormatted" Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('AnnualRevenueFormatted', '$1,000,000') .toSObject(); ``` -------------------------------- ### Bulk Field Assignment with SObjectField References Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Assigns multiple fields to an Account object at once using a Map of SObjectField references. ```apex // Using SObjectField references Account account = (Account)new sfab_FabricatedSObject(Account.class) .set(new Map { Account.Name => 'Test Account', Account.BillingCity => 'San Francisco', Account.Industry => 'Technology' }) .toSObject(); ``` -------------------------------- ### Set Account Fields using String Field Names Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Uses string field names for setting Account fields, offering flexibility for parent navigation and setting arbitrary relationship depths. Requires runtime validation. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'Test Account') .set('BillingCity', 'San Francisco') .toSObject(); ``` -------------------------------- ### Constructor(Type) Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Creates a FabricatedSObject of the specified type. This constructor is used to initialize a new SObject fabrication with a given SObject type. ```APIDOC ## Constructor(Type) ### Description Creates a FabricatedSObject of the specified type. ### Method Constructor ### Parameters #### Path Parameters - **sType** (Type) - Required - The SObject type to fabricate (e.g., `Account.class`, `Contact.class`) ### Request Example ```apex sfab_FabricatedSObject fabricatedAccount = new sfab_FabricatedSObject(Account.class); ``` ### Response #### Success Response - **sfab_FabricatedSObject instance** - The newly created sfab_FabricatedSObject instance. ``` -------------------------------- ### Fluent API Method Chaining Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/usage-guide.md Utilize the fluent API pattern by chaining setter and adder methods for concise and readable SObject creation. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'ACME Corp') .set('Industry', 'Technology') .set('BillingCity', 'San Francisco') .set('Owner', new sfab_FabricatedSObject(User.class).set('Username', 'sysadmin')) .add('Contacts', new sfab_FabricatedSObject(Contact.class).set('LastName', 'Smith')) .add('Contacts', new sfab_FabricatedSObject(Contact.class).set('LastName', 'Johnson')) .toSObject(); ``` -------------------------------- ### Setting Blob Field Values Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FieldValuePairNode.md Demonstrates how to set Blob field values using either a String (which is auto-converted) or a Blob object directly. This is useful when creating or updating SObjects with Blob fields like Attachments. ```apex // Using String (auto-converted) Attachment attachment = (Attachment)new sfab_FabricatedSObject(Attachment.class) .set('Body', 'File contents as string') .toSObject(); // Using Blob (direct) Attachment attachment = (Attachment)new sfab_FabricatedSObject(Attachment.class) .set(Attachment.Body, Blob.valueOf('File contents')) .toSObject(); ``` -------------------------------- ### Field Configuration Map Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/types.md Use a Map to configure fields by their SObjectField API name. Ensure the values match the expected data types for the fields. ```apex Map fieldsByReference = new Map { Account.Id => 'CustomId', Account.Name => 'Account Name', Account.LastModifiedDate => Date.newInstance(2017, 1, 1) }; ``` -------------------------------- ### Add Child Records to a Parent SObject Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Demonstrates how to add multiple child records to a parent SObject using the add() method for related lists. ```Apex Account account = new sfab_FabricatedSObject(Account.class) .set('Name', 'ACME Corp') .add('Opportunities', new sfab_FabricatedSObject(Opportunity.class).set('Name', 'Opp1')) .add('Opportunities', new sfab_FabricatedSObject(Opportunity.class).set('Name', 'Opp2')) .toSObject(); ``` -------------------------------- ### Set Multiple Fields in Bulk Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FabricatedSObject.md Use this method to set multiple fields and relationships in bulk using String names. It returns the current object for fluent chaining. ```Apex public sfab_FabricatedSObject set(Map fields) ``` ```Apex sfab_FabricatedSObject fabricatedContact = new sfab_FabricatedSObject(Contact.class) .set(new Map { 'Id' => 'Id-1', 'LastName' => 'Smith', 'Account.Name' => 'Account Name' }); ``` -------------------------------- ### Create Account with Relationships Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/README.md Nest sfab_FabricatedSObject instances within add() calls to define parent and child relationships. The add() method supports adding single objects or lists of objects. ```apex Account account = (Account)new sfab_FabricatedSObject(Account.class) .set('Name', 'ACME Corp') .add('Contacts', new sfab_FabricatedSObject(Contact.class) .set('LastName', 'Smith')) .add('Opportunities', new sfab_FabricatedSObject(Opportunity.class) .set('Name', 'Deal') .set('StageName', 'Prospecting')) .toSObject(); System.debug(account.Contacts.size()); // 1 System.debug(account.Opportunities[0].Name); // Deal ``` -------------------------------- ### Method: postBuildProcess(Object) Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/api-reference/sfab_FieldValuePairNode.md Applies post-deserialization processing, specifically for Blob fields which are set directly after JSON deserialization. ```APIDOC ## Method: postBuildProcess(Object) ### Description Applies post-deserialization processing to an SObject instance. This method is crucial for setting Blob field values that cannot be directly JSON serialized and deserialized. ### Parameters #### Path Parameters - **objectToProcess** (Object) - Required - The SObject instance to process (should be cast to SObject). ### Behavior - **Blob fields:** If the node's field is a Blob type, this method converts the stored value (which can be a Blob or a String) into a Blob and sets it directly on the provided `objectToProcess`. - **Non-Blob fields:** If the field is not a Blob type, this method does nothing, as the value would have already been set during the standard JSON deserialization process. ### Blob Conversion Logic - If the stored value is already a `Blob`, it is used directly. - If the stored value is a `String`, it is converted to a `Blob` using `Blob.valueOf(String)`. ### Request Example ```apex // Assume attachment is an SObject instance created from JSON deserialization // where the Body field was initially null due to Blob handling. Attachment attachment = (Attachment) new sfab_FabricatedSObject(Attachment.class) .set(Attachment.Body, 'file contents') // This sets the value internally .toSObject(); // During the toSObject() process, serialize() would return {} for Body. // Then, postBuildProcess() is called to apply the actual Blob value. // The example above demonstrates the intended usage within the sfab_FabricatedSObject class. ``` ``` -------------------------------- ### DescribeFieldResult Key Methods Source: https://github.com/mattaddy/sobjectfabricator/blob/master/_autodocs/types.md Lists important methods of DescribeFieldResult, providing metadata for a single field. ```apex String getName() String getRelationshipName() Schema.DisplayType getType() List getReferenceTo() ```