You need to sign in to do that
Don't have an account?
Antone Kom
Update Record Quick Action invoked by Batch Apex Class - Test class is failing to recognize that the records were updated, assert is failing.
Hello,
I am running into a strange issue - I have created a Record Update QuickAction on Contact object, which we have added on page layouts for users to be able to anonymize the contact record (for GDPR compliance purposes). This QuickAction uses Predefined Field Values to remove / obfuscate data on certain contact fields that contain personal info (Name, Email, Phone #, etc.) The action is working fine when invoked on a single record from the UI.
As part of our Sandbox refresh strategy, I am trying to invoke the same QuickAction via apex code to anonymize ALL contacts as a post-refresh task (Apex class that implements SandboxPostCopy interface). Since it should run on all records, I am invoking it from a Batchable class.
What I am running into is that in my test class, it appears in debug logs that invoking the QuickAction on the batch of records is successful, but when I re-query those records to do an assert to make sure they were updated, the query shows that the records have NOT been updated by the Quick Action.
Here is some sample code to illustrate:
Exceprts of DEBUG output when running the Apex Test:
Based on the above, it seems that the Batch ran successfully and the QuickAction executed successfully on the batch of 5 records, but the re-query afterwards (just before the AssertEquals statement) shows the original data before the update.
Any ideas what I might be missing here?
I am running into a strange issue - I have created a Record Update QuickAction on Contact object, which we have added on page layouts for users to be able to anonymize the contact record (for GDPR compliance purposes). This QuickAction uses Predefined Field Values to remove / obfuscate data on certain contact fields that contain personal info (Name, Email, Phone #, etc.) The action is working fine when invoked on a single record from the UI.
As part of our Sandbox refresh strategy, I am trying to invoke the same QuickAction via apex code to anonymize ALL contacts as a post-refresh task (Apex class that implements SandboxPostCopy interface). Since it should run on all records, I am invoking it from a Batchable class.
What I am running into is that in my test class, it appears in debug logs that invoking the QuickAction on the batch of records is successful, but when I re-query those records to do an assert to make sure they were updated, the query shows that the records have NOT been updated by the Quick Action.
Here is some sample code to illustrate:
global class SandboxBuild implements SandboxPostCopy{ final String CLASSNAME = '\n\n**** SandboxBuild.METHODNAME()'; global void runApexClass(SandboxContext context){ final string METHODNAME = CLASSNAME.replace('METHODNAME','runApexClass'); system.debug(LoggingLevel.INFO, METHODNAME.replace('**** ', '**** Inside ')); SandboxBuildHelper sbh = new SandboxBuildHelper(); sbh.anonymizeContacts(); } }
public class SandboxBuildHelper { public void anonymizeContacts() { // Query for selecting the contacts to anonymize - in this case ALL contacts String query = 'SELECT Id FROM Contact Limit 5'; // Invoke the batch job. BatchGDPRAnonymizeContacts bAnon = new BatchGDPRAnonymizeContacts(query); Id batchprocessid = Database.executeBatch(bAnon); System.debug('Returned batch process ID: ' + batchProcessId); } }
global class BatchGDPRAnonymizeContacts implements Database.Batchable<sObject> { global final String query; global BatchGDPRAnonymizeContacts(String q) { query=q; } global Database.QueryLocator start(Database.BatchableContext BC) { return Database.getQueryLocator(query); } global void execute(Database.BatchableContext BC, List<sObject> scope) { List<QuickAction.QuickActionRequest> reqs = new List<QuickAction.QuickActionRequest>(); List<QuickAction.QuickActionResult> results = new List<QuickAction.QuickActionResult>(); for(sObject s : scope){ Contact c = (Contact)s; system.debug('Contact: '+ c.FirstName+' '+c.LastName+' - '+c.Email+' - '+c.Phone); QuickAction.QuickActionRequest req = new QuickAction.QuickActionRequest(); req.quickActionName = Schema.Contact.QuickAction.GDPR_Anonymize_Contact; req.record = c; reqs.add(req); } results = QuickAction.performQuickActions(reqs); for(QuickAction.QuickActionResult r: results){ system.debug('getIds(): '+r.getIds()); system.debug('getSuccessMessage(): '+r.getSuccessMessage()); system.debug('isCreated(): '+r.isCreated()); system.debug('isSuccess(): '+r.isSuccess()); system.debug('getErrors(): '+r.getErrors()); } } global void finish(Database.BatchableContext BC){ // Get the ID of the AsyncApexJob representing this batch job // from Database.BatchableContext. // Query the AsyncApexJob object to retrieve the current job's information. AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id = :BC.getJobId()]; system.debug('Apex BatchGDPRAnonymizeContacts ' + a.Status); system.debug('The batch Apex job processed ' + a.TotalJobItems + ' batches with '+ a.NumberOfErrors + ' failures.'); } }
@isTest private class BatchGDPRAnonymizeContacts_Test { @isTest static void testbatch() { // create 200 test contacts - this simulates one execute. // Important - the Salesforce.com test framework only allows you to // test one execute List <Contact> cList = new List<Contact>(); Integer numContacts = 5; for(integer i = 0; i<numContacts; i++){ Contact c = new Contact (FirstName='test', LastName='Contact'+i, Email='test'+i+'@test.com', Phone='+1208555000'+i); cList.add(c); } insert cList; Test.StartTest(); String query = 'SELECT ID, FirstName, LastName, Email, Phone ' + 'FROM Contact ' + ' LIMIT ' + numContacts; BatchGDPRAnonymizeContacts batch = new BatchGDPRAnonymizeContacts(query); ID batchprocessid = Database.executeBatch(batch, 50); Test.StopTest(); List<Contact> cListAnon = [Select Id, FirstName, LastName, Email, Phone from Contact]; system.debug('cListAnon: ' + cListAnon); System.AssertEquals( numContacts, database.countquery('SELECT COUNT() FROM Contact WHERE FirstName=\'ANONYMOUS\'')); } }
Exceprts of DEBUG output when running the Apex Test:
12:50:12.990 (4209501390)|CODE_UNIT_STARTED|[EXTERNAL]|01pq0000000ajd6|BatchGDPRAnonymizeContacts 12:50:12.990 (4215187082)|SOQL_EXECUTE_BEGIN|[11]|Aggregations:0|SELECT ID, FirstName, LastName, Email, Phone FROM Contact 12:50:12.990 (4299212112)|SOQL_EXECUTE_END|[11]|Rows:5 12:50:12.990 (4325480890)|CODE_UNIT_FINISHED|BatchGDPRAnonymizeContacts 12:50:12.990 (4326373234)|CODE_UNIT_STARTED|[EXTERNAL]|01pq0000000ajd6|BatchGDPRAnonymizeContacts 12:50:12.990 (4347406438)|CODE_UNIT_STARTED|[EXTERNAL]|01pq0000000ajd6|BatchGDPRAnonymizeContacts 12:50:12.990 (4348454925)|USER_DEBUG|[20]|DEBUG|Contact: test Contact0 - test0@test.com - +12085550000 12:50:12.990 (4348661312)|USER_DEBUG|[20]|DEBUG|Contact: test Contact1 - test1@test.com - +12085550001 12:50:12.990 (4348743660)|USER_DEBUG|[20]|DEBUG|Contact: test Contact2 - test2@test.com - +12085550002 12:50:12.990 (4348811920)|USER_DEBUG|[20]|DEBUG|Contact: test Contact3 - test3@test.com - +12085550003 12:50:12.990 (4348877642)|USER_DEBUG|[20]|DEBUG|Contact: test Contact4 - test4@test.com - +12085550004 12:50:12.990 (4349377319)|DML_BEGIN|[27]|Op:PerformQuickAction|Type:QuickActionResult|Rows:5 . . . . 12:50:12.990 (4681351512)|DML_END|[27] 12:50:12.990 (4681899567)|USER_DEBUG|[29]|DEBUG|getIds(): (003q000000w1HK0AAM) 12:50:12.990 (4681941852)|USER_DEBUG|[30]|DEBUG|getSuccessMessage(): Contact details successfully anonymized. 12:50:12.990 (4681982207)|USER_DEBUG|[31]|DEBUG|isCreated(): false 12:50:12.990 (4682015050)|USER_DEBUG|[32]|DEBUG|isSuccess(): true 12:50:12.990 (4682105172)|USER_DEBUG|[33]|DEBUG|getErrors(): () 12:50:12.990 (4682171498)|USER_DEBUG|[29]|DEBUG|getIds(): (003q000000w1HK1AAM) 12:50:12.990 (4682187044)|USER_DEBUG|[30]|DEBUG|getSuccessMessage(): Contact details successfully anonymized. 12:50:12.990 (4682204942)|USER_DEBUG|[31]|DEBUG|isCreated(): false 12:50:12.990 (4682229456)|USER_DEBUG|[32]|DEBUG|isSuccess(): true 12:50:12.990 (4682260353)|USER_DEBUG|[33]|DEBUG|getErrors(): () 12:50:12.990 (4682313526)|USER_DEBUG|[29]|DEBUG|getIds(): (003q000000w1HK2AAM) 12:50:12.990 (4682328104)|USER_DEBUG|[30]|DEBUG|getSuccessMessage(): Contact details successfully anonymized. 12:50:12.990 (4682345912)|USER_DEBUG|[31]|DEBUG|isCreated(): false 12:50:12.990 (4682361731)|USER_DEBUG|[32]|DEBUG|isSuccess(): true 12:50:12.990 (4682389503)|USER_DEBUG|[33]|DEBUG|getErrors(): () 12:50:12.990 (4682436899)|USER_DEBUG|[29]|DEBUG|getIds(): (003q000000w1HK3AAM) 12:50:12.990 (4682450390)|USER_DEBUG|[30]|DEBUG|getSuccessMessage(): Contact details successfully anonymized. 12:50:12.990 (4682467749)|USER_DEBUG|[31]|DEBUG|isCreated(): false 12:50:12.990 (4682483932)|USER_DEBUG|[32]|DEBUG|isSuccess(): true 12:50:12.990 (4682510753)|USER_DEBUG|[33]|DEBUG|getErrors(): () 12:50:12.990 (4682555396)|USER_DEBUG|[29]|DEBUG|getIds(): (003q000000w1HK4AAM) 12:50:12.990 (4682568987)|USER_DEBUG|[30]|DEBUG|getSuccessMessage(): Contact details successfully anonymized. 12:50:12.990 (4682585831)|USER_DEBUG|[31]|DEBUG|isCreated(): false 12:50:12.990 (4682602455)|USER_DEBUG|[32]|DEBUG|isSuccess(): true 12:50:12.990 (4682629221)|USER_DEBUG|[33]|DEBUG|getErrors(): () 12:50:12.990 (4682654145)|CODE_UNIT_FINISHED|BatchGDPRAnonymizeContacts 12:50:12.990 (4718160419)|CODE_UNIT_FINISHED|BatchGDPRAnonymizeContacts 12:50:12.990 (4719016441)|CODE_UNIT_STARTED|[EXTERNAL]|01pq0000000ajd6|BatchGDPRAnonymizeContacts 12:50:12.990 (4726103588)|SOQL_EXECUTE_BEGIN|[44]|Aggregations:0|SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id = :tmpVar1 12:50:12.990 (4733869475)|SOQL_EXECUTE_END|[44]|Rows:1 12:50:12.990 (4734225747)|USER_DEBUG|[48]|DEBUG|Apex BatchGDPRAnonymizeContacts Completed 12:50:12.990 (4734367728)|USER_DEBUG|[49]|DEBUG|The batch Apex job processed 1 batches with 0 failures. 12:50:12.990 (4741437910)|CODE_UNIT_FINISHED|BatchGDPRAnonymizeContacts 12:50:12.990 (4743061969)|SOQL_EXECUTE_BEGIN|[25]|Aggregations:0|SELECT Id, FirstName, LastName, Email, Phone FROM Contact 12:50:12.990 (4747198855)|SOQL_EXECUTE_END|[25]|Rows:5 12:50:12.990 (4747514612)|USER_DEBUG|[26]|DEBUG|cListAnon: (Contact:{Id=003q000000w1HK0AAM, FirstName=test, LastName=Contact0, Email=test0@test.com, Phone=+12085550000}, Contact:{Id=003q000000w1HK1AAM, FirstName=test, LastName=Contact1, Email=test1@test.com, Phone=+12085550001}, Contact:{Id=003q000000w1HK2AAM, FirstName=test, LastName=Contact2, Email=test2@test.com, Phone=+12085550002}, Contact:{Id=003q000000w1HK3AAM, FirstName=test, LastName=Contact3, Email=test3@test.com, Phone=+12085550003}, Contact:{Id=003q000000w1HK4AAM, FirstName=test, LastName=Contact4, Email=test4@test.com, Phone=+12085550004}) 12:50:12.990 (4747700346)|SOQL_EXECUTE_BEGIN|[29]|Aggregations:0|SELECT COUNT() FROM Contact WHERE FirstName='ANONYMOUS' 12:50:12.990 (4752840759)|SOQL_EXECUTE_END|[29]|Rows:0 12:50:12.990 (4752943948)|EXCEPTION_THROWN|[29]|System.AssertException: Assertion Failed: Expected: 5, Actual: 0 12:50:12.990 (4753035742)|FATAL_ERROR|System.AssertException: Assertion Failed: Expected: 5, Actual: 0 Class.BatchGDPRAnonymizeContacts_Test.testbatch: line 30, column 1 12:50:12.990 (4753045670)|FATAL_ERROR|System.AssertException: Assertion Failed: Expected: 5, Actual: 0
Based on the above, it seems that the Batch ran successfully and the QuickAction executed successfully on the batch of 5 records, but the re-query afterwards (just before the AssertEquals statement) shows the original data before the update.
Any ideas what I might be missing here?
Update your code like below
Remove WHERE FirstName='ANONYMOUS' from query/.
Removing FirstName='ANONYMOUS' would allow the test class to pass but this assertion fails because the QuickAction has not really updated the records, which is what I want to test. I am not trying to just get the test class to pass for the sake of passing without testing the actual use case.