+ Start a Discussion
SteveOrgSteveOrg 

Help creating test class for Apex Trigger

I have created a simple trigger that would update all associated opportunities with a field on the account record upon update, however I'm not sure what the test method needs to be since all the examples I found relate to a new record being created.  Would appreciate any help.

 

Here is the code for my trigger:

 

trigger accountTrigger on Account (after insert,after update) 
{ 
  
List<account> accountWithOpptys = [select id,name,customaccount__c, (select id, name, customopportunities__c from Opportunities where accountId IN :Trigger.newMap.keySet()) 

from Account where Id IN :Trigger.newMap.keySet()]; 

for(Account a : accountWithOpptys)
  { 
  for(Opportunity o: a.Opportunities)
    { 
    o.customopportunities__c = a.customaccount__c; 
    update o;
    } 
  } 
}

 I was hoping there is someone that has done something similar where I could leverage your test case.  

 

 

davidjgriffdavidjgriff
You'll probably want to rework that trigger a bit:

1. You can ignore any inserts, because a new Account will never have any Opptys under it.
2. You should probably check any updated Accounts to see if the value has changed so you don't have to do unnecessary work.
3. NEVER issue any DML statements (insert, update, etc) within a loop. You'll run into governor limits very quickly that way.
4. You don't need that AccountId filter in your sub-select as it will only give you Opptys that are associated with the accounts in question anyway :)
5. Techincally, you could actually just query the Opportunity table to get opptys that are children of the accounts in question and then get the value on the appropriate account with something like "trigger.newMap.get(o.AccountId).customaccount__c"

I know that's a lot, and it doesn't really address your question, but it may help you think about that you need to do to write a test case (since, if you rework it, you are only checking updates to accounts where a certain value has changed...)
SteveOrgSteveOrg

Thanks so much for your response.  This is my first trigger, so I appreciate the recommendation as that is certainly a better design.  Based on your feedback I modified it slightly and was wondering if this would be the correct approach to checking whether the field was modified:

 

trigger accountTrigger on Account (after update) { 

//Assign the context before and after the change into a Map
Map<Id,Account> newAccountMap = Trigger.newMap;
Map<Id,Account> oldAccountMap = Trigger.oldMap;

trigger.newMap.get(o.AccountId).customaccount__c = fieldtoUpdate
  
List<account> accountWithOpptys = [select id,name,customaccount__c, (select id, name, customopportunities__c from Opportunities where accountId IN :Trigger.newMap.keySet()) 

]; 




for(Id AccountId:newAccountMap.keySet()){
 Account myNewAccount = newAccountMap.get(AccountId);
 Account myOldAccount = oldAccountMap.get(AccountId);

 if (myNewAccount.customaccount__c<> myOldAccount.customaccount__c){
   

  for(Account a : accountWithOpptys)
  { 
  for(Opportunity o: a.Opportunities)
    { 
    fieldtoUpdate = a.customaccount__c; 
    } 
  } 


 }
   

}

update fieldtoUpdate;

}

 

davidjgriffdavidjgriff

I was thinking more like this...(forgive me if there are typos or compile errors as I'm just typing this out in the browser)

 

trigger updateOpptysFromAccount on Account (after update) { 

    //make a set to hold account ids that we need
	Set<Id> acctIds = new Set<Id>();
	
	for(Account a : trigger.new){
		//check to see if our field has been changed
		if(a.CustomAccount__c != trigger.oldMap.get(a.Id).CustomAccount__c){
			
			acctIds.add(a.Id);
			
		}

	}
	
	if(!acctIds.isEmpty(){
	
		//get any opptys associated with the accounts that have been edited
		List<Opportunity> opptys = [SELECT Id,AccountId FROM Opportunity WHERE AccountID IN :acctIds];
		
		for(Opportunity o : opptys){
		
			o.CustomOpportunity__c = trigger.newMap.get(o.AccountId).CustomAccount__c;
			
		}
		
		update opptys;
		
	}


}

 

SteveOrgSteveOrg

No problem at all, I'm just happy to to receive any advice at this point.

 

I do get a compile error related to the line below.  unexpected token: '{',

 

 

But it made sense for the update to happen outside a for loop.  I hate to take any more your time, so I can take some time on my end to find the solution..

 

Thanks so much for all your help.

 

if(!acctIds.isEmpty(){

SwarnasankhaSwarnasankha

Hi Steve,

 

It is just a typo - missing a parentheses.

 

if(!acctIds.isEmpty()){

 

SteveOrgSteveOrg

Thanks so much!  Everything works great.  Now on to my test class :)

davidjgriffdavidjgriff
When putting together your test class, just think of the scenario you built the trigger to handle. You just need to recreate that situation and make sure that all code is executed and doesn't fail.

With recent API versions, you need to create all of your own test data within your test instance, so you'll be creating some dummy records to act on.