You need to sign in to do that
Don't have an account?
James Byron 26
Problem creating or editing object in Test
I have an issue with creating tests for a class that calculates a number and stores it i my salesforce database. I have a cstom object called "Application," which is related to a Contact object. I created a custom field in the Application object that will store the numberical value of a students for finacial aid purposes. I created an apex class to update the value of this number, and I am using that class through an after update trigger on the Application object. The API name for the Application object is EnrollmentrxRx__Enrollment_Opportunity__c. Here is the error that I'm getting:
The stack trace says "Class.TestCalculateFinAidIndex.updateIndexFromApplicationTest: line 12, column 1," which points to the update apps line in the following code. My Test class is below:
Here's my code for the class that I need to test:
Thank you for your help!
System.DmlException: Update failed. First exception on row 0 with id a0Bo00000047ZJSEA2; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, ApplicationTrigger: execution of AfterUpdate caused by: System.FinalException: Record is read-only Class.CalculateFinAidIndex.updateIndex: line 67, column 1 Class.CalculateFinAidIndex.updateIndexFromApplication: line 26, column 1 Trigger.ApplicationTrigger: line 14, column 1: []
The stack trace says "Class.TestCalculateFinAidIndex.updateIndexFromApplicationTest: line 12, column 1," which points to the update apps line in the following code. My Test class is below:
@isTest(SeeAllData=true) public class TestCalculateFinAidIndex { static testMethod void updateIndexFromApplicationTest() { List<EnrollmentrxRx__Enrollment_Opportunity__c> apps = new List<EnrollmentrxRx__Enrollment_Opportunity__c>(); apps.addall([SELECT Financial_Aid_Index__c,EnrollmentrxRx__Applicant__c,EnrollmentrxRx__Admissions_Status__c,Active_Application__c,Max_ACT_Composite__c,SAT_Superscore__c,EnrollmentrxRx__GPA__c,First_Generation__c FROM EnrollmentrxRx__Enrollment_Opportunity__c WHERE EnrollmentrxRx__Admissions_Status__c = 'Admit' AND Active_Application__c = true LIMIT 10]); System.assert(apps != null); System.assert(apps.size() > 0); for (EnrollmentrxRx__Enrollment_Opportunity__c app : apps) { app.Date_Last_Updated_Auto_FinAidIndex__c = Date.today(); } update apps; // this will call the trigger for (Integer i = 0; i < apps.size(); i++) { System.assert(apps[i].Financial_Aid_Index__c != null); System.assert(apps[i].Financial_Aid_Index__c > 0); } } }
Here's my code for the class that I need to test:
public class CalculateFinAidIndex { public static void updateIndexFromApplication(EnrollmentrxRx__Enrollment_Opportunity__c[] apps) { for (EnrollmentrxRx__Enrollment_Opportunity__c app : apps) { updateIndex(app); } update apps; } public static void updateIndex(EnrollmentrxRx__Enrollment_Opportunity__c app) { if (app.Active_Application__c && ((app.EnrollmentrxRx__Admissions_Status__c == 'Applied') || (app.EnrollmentrxRx__Admissions_Status__c == 'Complete') || (app.EnrollmentrxRx__Admissions_Status__c == 'Admit'))) { Integer finIndex = 0; Double act = app.Max_ACT_Composite__c; Double sat = app.SAT_Superscore__c; // or is it app.EnrollmentrxRx__Total_SAT_Score__c Double gpa = 0; // 25 Integer gender = 0; // 10 Integer race = 0; // 10 Integer legacy = 0; // 10 Integer firstGen = 0; // 10 Double testValue = 0; if (sat != null) sat = (sat / 2400) * 25; // assuming that the max is 2400 else sat = 0; if (act != null) act = (act / 36) * 25; //assuming that the max is 36 else act = 0; if (sat > act) testValue = sat; else testValue = act; Contact c = new Contact();//app.EnrollmentrxRx__Applicant__c; if (c.EnrollmentrxRx__Gender__c == 'Male') gender = 10; if (app.EnrollmentrxRx__GPA__c != null) { gpa = (app.EnrollmentrxRx__GPA__c / 4) * 25; if (gpa > 25) gpa = 25; } if (c.Race__c != 'White') race = 10; if (app.First_Generation__c) firstGen = 10; if (c.Legacy_Relationship__c != null) legacy = 10; finIndex += (Integer)testValue + (Integer)gpa + gender + race + legacy + firstGen; app.Financial_Aid_Index__c = finIndex; System.debug('Logging from UpdateIndex: ' + finIndex); } } }
Thank you for your help!
The parameter which you are passing to the updateIndexFromApplication() method is probably from 'trigger.new' list which is a 'read only' list for all the after triggers. else its trigger.old which is always a read only list. Can you check the following link and update the code accordingly..
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables_considerations.htm
All Answers
The parameter which you are passing to the updateIndexFromApplication() method is probably from 'trigger.new' list which is a 'read only' list for all the after triggers. else its trigger.old which is always a read only list. Can you check the following link and update the code accordingly..
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables_considerations.htm