You need to sign in to do that
Don't have an account?

How to Test Trigger Lines containing .addError or for loops
I am writing a test class for a trigger that has multiple for loops in it and When I run the test the lines that are not covered are the for loops.
Here is part of the trigger:
trigger AutoCreateIncident on Account (after update) { List<Case> c = new List<Case>(); for (Integer i = 0; i < Trigger.new.size(); i++) { Account newCase = Trigger.new[i]; Account OldCase = Trigger.old[i]; if(newCase.Operational_Status__c == 'Operational' && oldCase.Operational_Status__c == 'IT GO'){ if(newCase.Account_Services_Rep__c == 'Ade Adeyemi' || oldCase.Account_Services_Rep__c == 'Ade Adeyemi'){ for(Integer j = 0; j < 24; j++){ c.add(new Case(Type = 'Health Check', Reason__c = 'Health Check', AccountId = newCase.Id, OwnerId = '005700000016ePl', Priority = 'High', Due_date__c = System.today() + (j*30) + 1)); } } else if(newCase.Account_Services_Rep__c == 'Chris Nelson' || oldCase.Account_Services_Rep__c == 'Chris Nelson'){ for(Integer k = 0; k < 24; k++){ c.add(new Case(Type = 'Health Check', Reason__c = 'Health Check', AccountId = newCase.Id, OwnerId = '005700000016eQ4', Priority = 'High', Due_date__c = System.today() + (k*30) + 1)); } } else if(newCase.Account_Services_Rep__c == 'Deborah Kerr' || oldCase.Account_Services_Rep__c == 'Deborah Kerr' ){ for(Integer l = 0; l < 24; l++){ c.add(new Case(Type = 'Health Check', Reason__c = 'Health Check', AccountId = newCase.Id, OwnerId = '005700000016ePr', Priority = 'High', Due_date__c = System.today() + (l*30) + 1)); } } else if(newCase.Account_Services_Rep__c == 'Elyssa Kim' || oldCase.Account_Services_Rep__c == 'Elyssa Kim'){ for(Integer m = 0; m < 24; m++){ c.add(new Case(Type = 'Health Check', Reason__c = 'Health Check', AccountId = newCase.Id, OwnerId = '00570000001IbB3', Priority = 'High', Due_date__c = System.today() + (m*30) + 1)); } } } } insert c; }
I understand this is not the most efficent or best way to code this trigger, but this is how i have chosen to code it for now. The lines of code that I am not sure how to test are the for loop lines and the "c.add(new Case(" lines. any suggestions on how to tackle this one?
I also have another one that has a few Field.addErrors in it and I am not sure how to test those lines of code either
Thanks
To test your inner for loops you will likely need at least 3 test methods. In your test methods you simply have to create test data that meets the criteria. So first:
newCase.Operational_Status__c == 'Operational' && oldCase.Operational_Status__c == 'IT GO'
You'll need to insert a Case:
c.Operational_Status__c = 'Operational';
insert c;
c.Operational_Status__c = 'IT GO';
Test.startTest();
update c;
Test.stopTest();
But you'll also need the other criteria:
newCase.Account_Services_Rep__c == 'Ade Adeyemi' || oldCase.Account_Services_Rep__c == 'Ade Adeyemi'
So now you'll need:
c.Operational_Status__c = 'Operational';
c.Account_Services_Rep__c = 'Ade Adeyemi';
insert c;
c.Operational_Status__c = 'IT GO';
Test.startTest();
update c;
Test.stopTest();
The above should execute your first for loop and create 24 new Cases.
As for optimizing your code, why not make Account_Services_Rep__c a LOOKUP to the User? Then you can simply create 24 new cases where
OwnerId = Account_Services_Rep__c (assuming that Ade Adeyemi has owner id = '005700000016ePl')
OR if those aren't the same, why not allow a workflow rule or case assignment rule to make the ownership change for you? Then you don't have to have so many if/else.
Your assignment rule could be: If case type = Health Check and Account Services Rep = 'Ade Adeyemi' then assign the case to the owner with id 005700000016ePl.
You'd then only have a single inner for loop to test in your test method!
Good luck and check out: http://wiki.developerforce.com/index.php/An_Introduction_to_Apex_Code_Test_Methods
All Answers
To test your inner for loops you will likely need at least 3 test methods. In your test methods you simply have to create test data that meets the criteria. So first:
newCase.Operational_Status__c == 'Operational' && oldCase.Operational_Status__c == 'IT GO'
You'll need to insert a Case:
c.Operational_Status__c = 'Operational';
insert c;
c.Operational_Status__c = 'IT GO';
Test.startTest();
update c;
Test.stopTest();
But you'll also need the other criteria:
newCase.Account_Services_Rep__c == 'Ade Adeyemi' || oldCase.Account_Services_Rep__c == 'Ade Adeyemi'
So now you'll need:
c.Operational_Status__c = 'Operational';
c.Account_Services_Rep__c = 'Ade Adeyemi';
insert c;
c.Operational_Status__c = 'IT GO';
Test.startTest();
update c;
Test.stopTest();
The above should execute your first for loop and create 24 new Cases.
As for optimizing your code, why not make Account_Services_Rep__c a LOOKUP to the User? Then you can simply create 24 new cases where
OwnerId = Account_Services_Rep__c (assuming that Ade Adeyemi has owner id = '005700000016ePl')
OR if those aren't the same, why not allow a workflow rule or case assignment rule to make the ownership change for you? Then you don't have to have so many if/else.
Your assignment rule could be: If case type = Health Check and Account Services Rep = 'Ade Adeyemi' then assign the case to the owner with id 005700000016ePl.
You'd then only have a single inner for loop to test in your test method!
Good luck and check out: http://wiki.developerforce.com/index.php/An_Introduction_to_Apex_Code_Test_Methods
Well ... first off, this is not the best way to code this for a couple reasons. 1. You've hardcoded userids in here when you should query for those. But more importantly 2. You've got way too much coding to accomplish this and it's going to require more test code to cover it. Take a look at the modified example here:
trigger accountsAfterTrigger on Account (after update) {
Case[] c = new Case[0];
Map <Id, Account> newCase = Trigger.newMap;
Map <Id, Account> oldCase = Trigger.oldMap;
Map <String, Id> assignTable = new Map <String, Id> ();
assignTable.put('Ade Adeyemi','005700000016ePl');
assignTable.put('Chris Nelson','005700000016eQ4');
assignTable.put('Deborah Kerr','005700000016ePr');
assignTable.put('Elyssa Kim','00570000001IbB3');
for (Account a : Trigger.new) {
if ((a.Operational_Status__c == 'Operational') &&
(oldcase.get(a.id).Operational_Status__c == 'IT GO') &&
(assignTable.get(a.Owner.Name) != null)) {
for (Integer i = 0; i < 24; i++) {
c.add(new Case(Type = 'Health Check',
Reason__c = 'Health Check',
Accountid = a.id,
ownerid = assignTable.get(a.Owner.Name),
Priority = 'High',
Due_date__c = System.today() + (i*30) + 1
));
}
}
}
if (c.size() > 0) {insert c;}
}
I've simplied your 4 for loops down to a single one. This way you only have to insert a test account once for the code to get tested vs. the 4 times you would've had to do it before. All you need for test coverage here to get it to fire at a minimum is the following:
static testMethod void testAccount() {
Account a = new Account(Name='Test Account',
BillingState='CA',
BillingCountry='US',
Account_Services_Rep__c = 'Ade Adeyemi'
Operational_Status__c='IT GO');
insert a;
a.Operational_Status='Operational';
update a;
}
The original way you had it, you would've had to do this multiple times (for each account_services_rep__c you have).
Now the code I put in here that has the assignTable should really be done with a query to the user table instead but this will work also.