+ Start a Discussion
DaNae PetersonDaNae Peterson 

Test class keeps failing

I have written a trigger that creates a contact when a quote has been accepted.  It is working in Sandbox.  Here is the code:

trigger CreateContract on Quote (before update) {
    
   for(Quote q : trigger.new){
        

        if(q.Status == 'Accepted'){
            
      Account acct = [SELECT Id, Name, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry, ShippingStreet, ShippingCity, ShippingState, ShippingPostalCode, ShippingCountry FROM Account WHERE Id = :q.AccountId];
      Opportunity opp = [SELECT Id, Name, Total_MRC__c FROM Opportunity WHERE Id = :q.OpportunityId];
            
            List <Contract> co = [SELECT Id FROM Contract WHERE Opportunity__c = :opp.Id];
            List <Contract> cont = [SELECT Id FROM Contract WHERE Quote__c = :q.Id];
            if (cont.size() <= 0){

          Contract ct = new Contract();
            
            ct.AccountId = acct.Id;
            ct.Status = 'Draft';
            ct.Opportunity__c = opp.Id;
            ct.Quote__c = q.Id;
            ct.BillingStreet = acct.BillingStreet;
            ct.BillingCity = acct.BillingCity;
            ct.BillingState = acct.BillingState;
            ct.BillingPostalCode = acct.BillingPostalCode;
            ct.BillingCountry = acct.BillingCountry;
            ct.salesReach__Contract_Monthly_Billing__c = opp.Total_MRC__c;
                
            insert ct;
                
                opp.StageName = 'Contract Requested by Client';
                update opp;
            }
        }
                
    }
            
}

I am trying to write the associated test class so I can push to production.  However I keep getting failed statuses when I click "Run Test" such as:

System.DmlException: Update failed. First exception on row 0 with id 0Q01800000008xyCAA; first error:
CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CreateContract: execution of AfterUpdate
caused by: System.QueryException: List has no rows for assignment to SObject
Trigger.CreateContract: line 8, column 1: []

Here is what I have so far for the test class:

@isTest
public class TestCreateContract {
    public static testmethod void TestUpdateChildAccounts(){
        Account a = new Account();
        a.Name = 'Test Account';
        a.salesReach__Agent_Account_Company_Name__c = '001a000001DbY9F';
        a.salesReach__Agent_Contact_Name__c = '003a000001XKLvE';
        a.BillingStreet = '1340 S Market St.';
        a.BillingCity = 'T or C';
        a.BillingState = 'NM';
        a.BillingPostalCode = '87901';
        a.BillingCountry = 'USA';
        a.ShippingStreet = '1340 S Market St.';
        a.ShippingCity = 'T or C';
        a.ShippingState = 'NM';
        a.ShippingPostalCode = '87901';
        a.ShippingCountry = 'USA';
        insert a;  
        
        Opportunity o = new Opportunity();
        o.Name = 'Telecom Potential Sale';
        o.AccountId = a.Id;
        o.salesReach__Agent_Account_Company_Name__c = a.salesReach__Agent_Account_Company_Name__c;
        o.salesReach__Agent_Contact_Name__c = a.salesReach__Agent_Contact_Name__c;
        o.CloseDate = date.today();
        o.StageName = 'Quote Requested By Client';
        o.Opportunity_Type__c = 'Renew Existing Service';
        o.Opportunity_Contact__c = '003a0000028fI7L';
        insert o;
        
        Quote q = new Quote();
        q.Name = 'Telecom Potential Sale - Quote';
        q.ExpirationDate = o.Quote_Expiration_Date__c;
        q.ContactId = o.Opportunity_Contact__c;
        q.Status = 'Draft';
        q.OpportunityId = o.Id;
        insert q;
        
        q.Status = 'Accepted';
        update q;
        
    }

}


Can someone please help me fix this?  Thank you!
Best Answer chosen by DaNae Peterson
Anupam RastogiAnupam Rastogi
Hi Peterson,

I imported your code into my Org and tested and could replicate the issue.

The problem is that the SOQL for getting the Account in the Trigger is not retrieving any record. Therefore there is nothing that can be assigned to the acct object.

I could solve the issue and get 100 % code coverage by interchanging the position of the SOQL for Account & Opportunity and using Opportunity to get the Account record rather than Quote. Here is the modified code for the same. It has everything else same just that the SOQLs have changed position. Test it at your end.
trigger CreateContract on Quote (before update) {
    
    for(Quote q : trigger.new){
        
        
        if(q.Status == 'Accepted'){
            
            //--- Moved this SOQL above the Account SOQL
            Opportunity opp = [SELECT Id, Name, Total_MRC__c, AccountId FROM Opportunity WHERE Id = :q.OpportunityId];

            //--- Used Quote's Opportunity rather than Quote for getting Account
            Account acct = [SELECT Id, Name, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry, ShippingStreet, ShippingCity, ShippingState, ShippingPostalCode, ShippingCountry FROM Account WHERE Id = :opp.AccountId];            
            
            List <Contract> co = [SELECT Id FROM Contract WHERE Opportunity__c = :opp.Id];
            List <Contract> cont = [SELECT Id FROM Contract WHERE Quote__c = :q.Id];
            if (cont.size() <= 0){
                
                Contract ct = new Contract();
                
                ct.AccountId = acct.Id;
                ct.Status = 'Draft';
                ct.Opportunity__c = opp.Id;
                ct.Quote__c = q.Id;
                ct.BillingStreet = acct.BillingStreet;
                ct.BillingCity = acct.BillingCity;
                ct.BillingState = acct.BillingState;
                ct.BillingPostalCode = acct.BillingPostalCode;
                ct.BillingCountry = acct.BillingCountry;
                ct.salesReach__Contract_Monthly_Billing__c = opp.Total_MRC__c;
                
                insert ct;
                
                opp.StageName = 'Contract Requested by Client';
                update opp;
            }
        }
        
    }
    
}

Thanks
AR

If this solves your problem then please mark it as best answer.

All Answers

Anupam RastogiAnupam Rastogi
Hi Peterson,

I imported your code into my Org and tested and could replicate the issue.

The problem is that the SOQL for getting the Account in the Trigger is not retrieving any record. Therefore there is nothing that can be assigned to the acct object.

I could solve the issue and get 100 % code coverage by interchanging the position of the SOQL for Account & Opportunity and using Opportunity to get the Account record rather than Quote. Here is the modified code for the same. It has everything else same just that the SOQLs have changed position. Test it at your end.
trigger CreateContract on Quote (before update) {
    
    for(Quote q : trigger.new){
        
        
        if(q.Status == 'Accepted'){
            
            //--- Moved this SOQL above the Account SOQL
            Opportunity opp = [SELECT Id, Name, Total_MRC__c, AccountId FROM Opportunity WHERE Id = :q.OpportunityId];

            //--- Used Quote's Opportunity rather than Quote for getting Account
            Account acct = [SELECT Id, Name, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry, ShippingStreet, ShippingCity, ShippingState, ShippingPostalCode, ShippingCountry FROM Account WHERE Id = :opp.AccountId];            
            
            List <Contract> co = [SELECT Id FROM Contract WHERE Opportunity__c = :opp.Id];
            List <Contract> cont = [SELECT Id FROM Contract WHERE Quote__c = :q.Id];
            if (cont.size() <= 0){
                
                Contract ct = new Contract();
                
                ct.AccountId = acct.Id;
                ct.Status = 'Draft';
                ct.Opportunity__c = opp.Id;
                ct.Quote__c = q.Id;
                ct.BillingStreet = acct.BillingStreet;
                ct.BillingCity = acct.BillingCity;
                ct.BillingState = acct.BillingState;
                ct.BillingPostalCode = acct.BillingPostalCode;
                ct.BillingCountry = acct.BillingCountry;
                ct.salesReach__Contract_Monthly_Billing__c = opp.Total_MRC__c;
                
                insert ct;
                
                opp.StageName = 'Contract Requested by Client';
                update opp;
            }
        }
        
    }
    
}

Thanks
AR

If this solves your problem then please mark it as best answer.
This was selected as the best answer
DaNae PetersonDaNae Peterson
This worked great, thank you!