/** * @description Test Data Factory for creating consistent test data across all test classes. * Use this pattern to avoid hardcoded test data and ensure test isolation. * * USAGE: * List accounts = TestDataFactory.createAccounts(5); * insert accounts; * * // Or with auto-insert: * List accounts = TestDataFactory.createAndInsertAccounts(5); * * @created {{Date}} */ @IsTest public class TestDataFactory { // ═══════════════════════════════════════════════════════════════════════════ // ACCOUNT METHODS // ═══════════════════════════════════════════════════════════════════════════ /** * @description Creates Account records without inserting * @param count Number of accounts to create * @return List of Account records (not inserted) */ public static List createAccounts(Integer count) { List accounts = new List(); for (Integer i = 0; i < count; i++) { accounts.add(new Account( Name = 'Test Account ' + i, Industry = 'Technology', BillingStreet = '123 Test Street', BillingCity = 'San Francisco', BillingState = 'CA', BillingPostalCode = '94105', BillingCountry = 'USA', Phone = '555-000-' + String.valueOf(i).leftPad(4, '0'), Website = 'https://testaccount' + i + '.example.com' )); } return accounts; } /** * @description Creates and inserts Account records * @param count Number of accounts to create * @return List of inserted Account records */ public static List createAndInsertAccounts(Integer count) { List accounts = createAccounts(count); insert accounts; return accounts; } /** * @description Creates Account with specific attributes * @param name Account name * @param industry Industry value * @return Account record (not inserted) */ public static Account createAccount(String name, String industry) { return new Account( Name = name, Industry = industry, BillingCity = 'San Francisco', BillingState = 'CA', BillingCountry = 'USA' ); } // ═══════════════════════════════════════════════════════════════════════════ // CONTACT METHODS // ═══════════════════════════════════════════════════════════════════════════ /** * @description Creates Contact records without inserting * @param count Number of contacts to create * @param accountId Parent account ID * @return List of Contact records (not inserted) */ public static List createContacts(Integer count, Id accountId) { List contacts = new List(); for (Integer i = 0; i < count; i++) { contacts.add(new Contact( FirstName = 'Test', LastName = 'Contact ' + i, AccountId = accountId, Email = 'testcontact' + i + '@example.com', Phone = '555-001-' + String.valueOf(i).leftPad(4, '0'), Title = 'Test Title ' + i, MailingStreet = '456 Test Ave', MailingCity = 'San Francisco', MailingState = 'CA', MailingPostalCode = '94105', MailingCountry = 'USA' )); } return contacts; } /** * @description Creates and inserts Contact records * @param count Number of contacts to create * @param accountId Parent account ID * @return List of inserted Contact records */ public static List createAndInsertContacts(Integer count, Id accountId) { List contacts = createContacts(count, accountId); insert contacts; return contacts; } // ═══════════════════════════════════════════════════════════════════════════ // LEAD METHODS // ═══════════════════════════════════════════════════════════════════════════ /** * @description Creates Lead records without inserting * @param count Number of leads to create * @return List of Lead records (not inserted) */ public static List createLeads(Integer count) { List leads = new List(); for (Integer i = 0; i < count; i++) { leads.add(new Lead( FirstName = 'Test', LastName = 'Lead ' + i, Company = 'Test Company ' + i, Email = 'testlead' + i + '@example.com', Phone = '555-002-' + String.valueOf(i).leftPad(4, '0'), Status = 'Open - Not Contacted', Industry = 'Technology', LeadSource = 'Web' )); } return leads; } /** * @description Creates and inserts Lead records * @param count Number of leads to create * @return List of inserted Lead records */ public static List createAndInsertLeads(Integer count) { List leads = createLeads(count); insert leads; return leads; } // ═══════════════════════════════════════════════════════════════════════════ // OPPORTUNITY METHODS // ═══════════════════════════════════════════════════════════════════════════ /** * @description Creates Opportunity records without inserting * @param count Number of opportunities to create * @param accountId Parent account ID * @return List of Opportunity records (not inserted) */ public static List createOpportunities(Integer count, Id accountId) { List opportunities = new List(); for (Integer i = 0; i < count; i++) { opportunities.add(new Opportunity( Name = 'Test Opportunity ' + i, AccountId = accountId, StageName = 'Prospecting', CloseDate = Date.today().addDays(30 + i), Amount = 10000 * (i + 1) )); } return opportunities; } /** * @description Creates and inserts Opportunity records * @param count Number of opportunities to create * @param accountId Parent account ID * @return List of inserted Opportunity records */ public static List createAndInsertOpportunities(Integer count, Id accountId) { List opportunities = createOpportunities(count, accountId); insert opportunities; return opportunities; } // ═══════════════════════════════════════════════════════════════════════════ // CASE METHODS // ═══════════════════════════════════════════════════════════════════════════ /** * @description Creates Case records without inserting * @param count Number of cases to create * @param accountId Parent account ID (optional) * @param contactId Related contact ID (optional) * @return List of Case records (not inserted) */ public static List createCases(Integer count, Id accountId, Id contactId) { List cases = new List(); for (Integer i = 0; i < count; i++) { cases.add(new Case( Subject = 'Test Case ' + i, Description = 'Test case description ' + i, Status = 'New', Priority = 'Medium', Origin = 'Web', AccountId = accountId, ContactId = contactId )); } return cases; } /** * @description Creates and inserts Case records * @param count Number of cases to create * @param accountId Parent account ID (optional) * @param contactId Related contact ID (optional) * @return List of inserted Case records */ public static List createAndInsertCases(Integer count, Id accountId, Id contactId) { List cases = createCases(count, accountId, contactId); insert cases; return cases; } // ═══════════════════════════════════════════════════════════════════════════ // USER METHODS (for System.runAs testing) // ═══════════════════════════════════════════════════════════════════════════ /** * @description Creates a test User with specified profile * Use with System.runAs() for permission testing * @param profileName Name of the profile to assign * @param uniqueIdentifier Unique string to avoid duplicate usernames * @return User record (not inserted) */ public static User createUser(String profileName, String uniqueIdentifier) { Profile p = [SELECT Id FROM Profile WHERE Name = :profileName LIMIT 1]; String uniqueEmail = uniqueIdentifier + '@testuser.example.com'; String uniqueUsername = uniqueIdentifier + '@testuser.example.com.test'; return new User( FirstName = 'Test', LastName = 'User ' + uniqueIdentifier, Email = uniqueEmail, Username = uniqueUsername, Alias = uniqueIdentifier.left(8), ProfileId = p.Id, TimeZoneSidKey = 'America/Los_Angeles', LocaleSidKey = 'en_US', EmailEncodingKey = 'UTF-8', LanguageLocaleKey = 'en_US' ); } /** * @description Creates and inserts a test User * @param profileName Name of the profile to assign * @param uniqueIdentifier Unique string to avoid duplicate usernames * @return Inserted User record */ public static User createAndInsertUser(String profileName, String uniqueIdentifier) { User u = createUser(profileName, uniqueIdentifier); insert u; return u; } // ═══════════════════════════════════════════════════════════════════════════ // CUSTOM OBJECT METHODS (Template) // ═══════════════════════════════════════════════════════════════════════════ /** * @description Template for custom object creation * Copy and modify for your custom objects * @param count Number of records to create * @return List of custom object records (not inserted) */ /* public static List createCustomObjects(Integer count) { List records = new List(); for (Integer i = 0; i < count; i++) { records.add(new Custom_Object__c( Name = 'Test Record ' + i, Custom_Field__c = 'Value ' + i // Add more fields as needed )); } return records; } public static List createAndInsertCustomObjects(Integer count) { List records = createCustomObjects(count); insert records; return records; } */ // ═══════════════════════════════════════════════════════════════════════════ // UTILITY METHODS // ═══════════════════════════════════════════════════════════════════════════ /** * @description Generates a unique string for test data * Useful for avoiding unique constraint violations * @return Unique string based on timestamp */ public static String generateUniqueString() { return String.valueOf(Datetime.now().getTime()) + String.valueOf(Math.random()).substring(2, 8); } /** * @description Creates a map of records by a specified field * Useful for test assertions * @param records List of SObjects * @param fieldName API name of the field to use as key * @return Map with field values as keys */ public static Map createMapByField(List records, String fieldName) { Map recordMap = new Map(); for (SObject record : records) { String keyValue = String.valueOf(record.get(fieldName)); recordMap.put(keyValue, record); } return recordMap; } }