function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion

Problem changing some fields in Opportunity



I need to check to see when an opportunity is set to isWon and take a few actions on it and some other objects. I created a trigger that fires on all of the after events for opportunity and reads the isWon boolean on the list of incoming opportunity objects. OK, so far, so good. Now my problem is that I'm writing a test where I create an opportunity object but I need to set the isWon field. Apparently that is a read-only field. I tried setting the stageName to 'Closed/Won' but that didn't change the isWon field. How can I simulate the closing of an opportunity into the 'Closed/Won' state and set the isWon field?






You have to update the Opportunity StageName field from a non-closed/won value, to a closed/won value. Make sure when you set the StageName property in your test case that you use the exact same spacing and capitalization as the "Won" picklist value from the Stage field.


That sounds very reasonable, however my test tells me that I am not getting the results I had hoped for. Here is a snippet from my test code:

		// Create  opportunity - note we're not using payments, 
		// we're using the opportunity for the amount
		Opportunity opportunity = new Opportunity();        
		opportunity.Amount = 5000.00;
		opportunity.Name = 'Yodeling Opportunity';
		opportunity.StageName = 'Prospecting';
		opportunity.CloseDate =;
        insert opportunity;
		opportunity.StageName = 'Closed/Won';
		update opportunity;



The trigger that is kicked off by the update has a System.debug statement that tells me the value of the isWon field:

	// Only check opportunities that have been set to won
	List<Opportunity> opportunities = new List<Opportunity>();
	for (Integer i = 0; i <; i++) {
		System.debug('* Opportunity: '+opportunity.Name+' = '[i].IsWon+' Trigger.old.isWon = '+Trigger.old[i].isWon);
		if ([i].isWon == true && Trigger.old[i].isWon == false) {



And unfortunately my output is not what I'd like to see:

14:28:36.436|USER_DEBUG|[5,3]|DEBUG|* Opportunity: Name = false Trigger.old.isWon = false


I was expecting to see = true


Any ideas what I might be doing wrong here?







It should look something like this:


trigger UpdateWonOpp (after insert, after update)
	List<Opportunity> wonOpps = new List<Opportunnity>();
	for(Opportunity o :
		//make sure the updated opportunity is set to won and was not before
		if(o.IsWon && !Trigger.oldMap.get(o.Id).IsWon)
			//add your opportunity field updates here
			//o.Amount = 1000.00
	//update opportunity if any exist
	if(wonOpps.size() > 0)
		update wonOpps;



Your test case would look something like this:


static testMethod void positiveTest()
	Opportunity o = new Opportunity();
	o.Amount = 5000.00;
	o.Name = 'Test Opportunity';
	o.StageName = 'Prospecting'; //a value that is not considered "Won"
	o.CloseDate =;
	insert o;
	//update the opportunity stage to a WON value
	o.StageName = '<insert_WON_stagename_here>';
	update o;
	Opportunity oTest = [SELECT Id, StageName, IsWon FROM Opportunity WHERE Id=:o.Id];
	system.assertEquals(true, oTest.IsWon);
	//any other actions taken should have their values asserted here


Let me know if you have any questions...