I have a class which implements Schedulable interface. All it does is, query some list of records and mark them as 'COMPLETE' in the end.
Class looks like following:
global class MyScheduledClass implements Schedulable{
global void execute(SchedulableContext ctx) {
// Run a SOQL to get list of records of some criteria and mark their status as complete.
List<Database.SaveResult> lstResults = Database.update(lstResultsToUpdate, false);
logErrorsIfAny(lstResults);
}
private void logErrorsIfAny(List<Database.SaveResult> lstSaveResult){
for(Database.SaveResult aResult: lstSaveResult){
if(aResult.isSuccess() == false){
for (Database.Error err : aResult.getErrors()){
System.debug('Error while updating id: '+aResult.getId()+' Message: '+err.getMessage());
}
}
}
}
In the test, I am trying to run the test method as a read-only user or an integration user which has a minimal access and does not have an access to modify any data. But, I believe the running user is just putting the job in the queue and Salesforce is running the job and due to that it is not hitting the error.
Here's how my part of test class looks like:
Test.startTest();
User readOnlyUser = createUser();
System.runAs(readOnlyUser){
try{
String jobId = System.schedule('ScheduledApexTest', CRON_EXP, new MyScheduledClass());
}catch(Exception e){
System.assert(e.getMessage().contains('Error while updating save attempt id:'));
}
}
Test.stopTest();
I am not sure how to test the Database.Error piece of code in the Scheduled job.
Best Answer
Place @testvisible annotation above logerrorsifany
in test class
make a record that will fire a validation rule or throw an error
put in list
use database.upsert
pass the upsert return into your now testvisible method
basically, if you use testvisible you just have to make a record fail to upsert then you can pass it to that class. Maybe you have a simpler solution, you can throw the record against a validation rule depending what you have in your system
best of luck