+ Start a Discussion
Joseph WinterJoseph Winter 

Testing Trigger: Object fields not being updated in test after update?

Hi,
Here I have made a trigger that;
- When an Opportunity is set to 'Closed Won' or 'Closed Lost', set all Opportunities belonging to the same Account to 'Closed Lost';
 

trigger OppsChangeCloses on Opportunity (after update) {
	if(AvoidRecursion.isFirstRun()){
		List<Opportunity> opps = [SELECT Id, StageName, AccountId FROM Opportunity WHERE Id IN :Trigger.new];

		for(Opportunity o: opps){

			System.debug('Opportunity Id:' + o.Id + ' | New-StageName = ' + o.StageName + ' | Old-StageName = ' + trigger.oldMap.Get(o.id).StageName); 

			//If opportunity has had its StageName updated
			if((o.StageName == 'Closed Won' || o.StageName== 'Closed Lost' ) && o.StageName != trigger.oldMap.Get(o.id).StageName){
				//List accounts with affected opportunities
				List<Account> accounts = [SELECT Id, (SELECT Id, StageName, Name FROM Opportunities) FROM Account WHERE Id = :o.AccountId];
				System.debug('Account ID : ' + o.accountId);
				for(Account a :accounts){
					for(Opportunity relatedOpp : a.opportunities){
						if(relatedOpp.id != o.id){
							System.debug('Other Op ID: ' + relatedOpp.Id + ' | Other Op Name: '+ relatedOpp.Name );

							System.debug('StageName Before: ' + relatedOpp.stageName);
							relatedOpp.stageName = 'Closed Lost';
							System.debug('StageName After: ' + relatedOpp.stageName);

							update relatedOpp;
						}
					}
				}
			}
		}
	}
}

The debugging I have done on the class seem to imply it should work, but my testing class disagrees.
 
@isTest
private class testOppsChangeCloses {

	static List<Opportunity> opps;
	static List<Account> accs;


	static void setup(){
		opps = new List<Opportunity>();
		accs = new List<Account>();

		Account a1 = new Account(Name = 'Test1');
		Account a2 = new Account(Name = 'Test2');
		accs.add(a1);
		accs.add(a2);
		insert accs;

		Opportunity o1 = new Opportunity(Name = 'TestOp1', CloseDate = (System.Today() + 7), StageName = 'Prospecting', AccountID = a1.Id);
		Opportunity o2 = new Opportunity(Name = 'TestOp2', CloseDate = (System.Today() + 7), StageName = 'Prospecting', AccountID = a1.Id);	
		Opportunity o3 = new Opportunity(Name = 'TestOp3', CloseDate = (System.Today() + 7), StageName = 'Prospecting', AccountID = a2.Id);
		Opportunity o4 = new Opportunity(Name = 'TestOp4', CloseDate = (System.Today() + 7), StageName = 'Prospecting', AccountID = a2.Id);	
		opps.add(o1);
		opps.add(o2);
		opps.add(o3);
		opps.add(o4);
		
		insert opps;

	}
	
	@isTest static void testOne() {
		Test.startTest();
		setup();

		//Change TestOp1 StageName to 'Close Won'
		System.debug('StageName Before Change: ' + opps[1].StageName);
		opps[0].StageName = 'Closed Won';
		update opps[0];
		System.debug('StageName After Change: ' + opps[1].StageName);
		System.debug('TestOp2 ID: ' + opps[1].ID + ' | TestOp2 Name' + opps[1].Name);

		//Is TestOp1's Stage 'Closed Won'?
		System.assertEquals('Closed Won', opps[0].StageName);
		
		//Is TestOp2's Stage 'Closed Lost'?
		System.assertEquals('Closed Lost', opps[1].StageName);

		Test.stopTest();
	
	}
	
	
}

The output of the debug lines are as follows;
 User-added image
As you can see, within the trigger, any related opportunities (of which there is one, TestOp2), are updated to 'Closed Lost'.
But in the Test methord, after the first opportunity is updated, the related opportunity seems to remain as 'Prospecting'

I know the code is quite messy and inefficient (I was to rework this after i got this working), but I would really appreciate a hand here. I may have just misconstructed the test class.

Thanks

Raj VakatiRaj Vakati
Below code is the culprit. you are trying to update the record from the list at zero position and print the debugs from the 1st position 
//Change TestOp1 StageName to 'Close Won'
		System.debug('StageName Before Change: ' + opps[1].StageName);
		opps[0].StageName = 'Closed Won';
		update opps[0];
		System.debug('StageName After Change: ' + opps[1].StageName);
		System.debug('TestOp2 ID: ' + opps[1].ID + ' | TestOp2 Name' + opps[1].Name);