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
Osiris77706Osiris77706 

Insert failed in Test class for trigger

Hello,

    What I’m trying to do is create a trigger that sets a checkbox field (True/False) on Opportunity called "Is New Customer". This trigger should grab the accountID that is associated with the Opportunity that fired the trigger. It should then search for the most recent Opportunity with that same Account attached to it. If the Opportunity has a close date longer than 5 years ago, it should mark the "Is New Customer" as true on the Opportunity that fired the trigger. Now I believe that I have the trigger coded correctly, but I’m having some trouble with the test class. Here’s my code.

TRIGGER:

trigger setIsNewCustomer on Opportunity (after update, after insert)
{

for (Opportunity opp: trigger.new)
    {
        List<Opportunity> past_opps = new List<Opportunity>([select id, AccountId, IsNewCustomer__c, IsWon FROM Opportunity WHERE AccountId =: opp.AccountId AND IsWon = True ORDER BY CloseDate DESC LIMIT 1]);
      
        if(past_opps.size() < 1)
        {
            opp.IsNewCustomer__c = True;
        }
        for(Opportunity o: past_opps)
        {
            if(o.CloseDate <= date.today().addDays(-1825))
            {
                opp.IsNewCustomer__c = True;

            }

        }
      
          
        upsert opp;
    }
  
}

TEST CLASS

@isTest
private class setNewCustomerTest {
  static testMethod void testIsNewCustomer()
  {
     Opportunity a = new Opportunity(Name='testOpp', StageName ='testStage', closeDate = (date.today().addDays(10 * 365 * -1)));
   
     insert a;
   
   
   
     Opportunity[] opp_list = new List<Opportunity>();
             
    
      opp_list.add(new Opportunity(Name='testOpp', StageName ='testStage', closeDate = (date.today().addDays(10 * 365 * -1))));
      opp_list.add(new Opportunity(Name='testOpp', StageName ='testStage', closeDate = (date.today().addDays(7 * 365 * -1))));
      opp_list.add(new Opportunity(Name='testOpp', StageName ='testStage', closeDate = (date.today().addDays(6 * 365 * -1))));
      opp_list.add(new Opportunity(Name='testOpp', StageName ='testStage', closeDate = (date.today().addDays(5 * 365 * -1))));
      opp_list.add(new Opportunity(Name='testOpp', StageName ='testStage', closeDate = (date.today().addDays(3 * 365 * -1))));
      opp_list.add(new Opportunity(Name='testOpp', StageName ='testStage', closeDate = (date.today().addDays(2 * 365 * -1))));

      for(Opportunity opp: opp_list){
          insert opp;
      }
         
      List<Opportunity> opp_list2 = new List<Opportunity>([select id, AccountId, IsNewCustomer__c FROM Opportunity WHERE AccountId = '0013000000InnFdAAJ']);
    
      for (Opportunity o : opp_list2)
          {
               System.debug('Is New Customer, after insert' + o.IsNewCustomer__c);
          }
    
    
       for(Opportunity opp2: opp_list2){
          insert opp2;
      }

  }

}

ERROR

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, setIsNewCustomer: execution of BeforeInsert

caused by: System.SObjectException: DML statment cannot operate on trigger.new or trigger.old

Trigger.setIsNewCustomer: line 23, column 1: []


I am relatively new to Apex triggers and test classes, so I am kind of stuck on this one. Also I understand that my test class may not be very thorough. I’m hoping someone here can give me a little help with this error and maybe a push in the right direction for a better test class.

Thank You!
Blake TanonBlake Tanon
first let me start by saying you should not be doing DML actions inside of loops.  Second, I beleive your issue is you're tring to upsert a trigger.new - the record your trigger is working on.  When you make changes to a record that is in a trigger you do not need to use a DML statement - it will update on its own.