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
DaNae PetersonDaNae Peterson 

Need a test class to cover a trigger AND class with a future method

Hi all!  I am still fairly new to development and need help writing a test class for a class I have developed (my experience is with triggers).  I am trying to autosync a quote to an opportunity upon creation and after studying some blog posts I came up with the following class:

public class QuoteAutoSyncUtil
    {
        @future
        public static void syncQuote(Map<Id, Id> quoteMap)
        {
            List<Opportunity> oppList = new List<Opportunity>();
           
            for(Id currentQuote : quoteMap.keyset())
            {
                Opportunity opp = new Opportunity();
                opp.Id = quoteMap.get(currentQuote);
                opp.SyncedQuoteId = currentQuote;
                oppList.add(opp);
            }
           
            Integer oppSize = oppList.size();
            update oppList[oppSize -1 ];
     
        }
       
    }

And the following trigger:

trigger QuoteAutoSync on Quote (after insert)
    {
        Map<Id, Id> quoteMap = new Map<Id, Id>();
        for(Quote currentQuote : Trigger.New)
        {
          if(currentQuote.ExpirationDate != NULL)
          {
              quoteMap.put(currentQuote.Id, currentQuote.OpportunityId);
          }
        }
       
        QuoteAutoSyncUtil.syncQuote(quoteMap);
    }

It is working perfectly in Sandbox but I am getting stuck on the test class.  This is what I have so far:

@isTest
public class AutoSyncQuote {

    public static testmethod void TestAutoSyncQuote(){
       Account a = new Account();
        a.Name = 'Test Account';
        a.salesReach__Agent_Account_Company_Name__c = '001a000001DbY9F';
        a.salesReach__Agent_Contact_Name__c = '003a000001iM38p';
        a.Account_Status__c = 'Active';
        a.Diamond_Account__c = True;
        a.Net_One__c = False;
        
        Insert a;
        
       Opportunity opp = new Opportunity();
        opp.Name = 'Telecom Product or Service';
        opp.CloseDate = Date.today();
        opp.StageName = 'Quote Requested By Client';
        opp.Opportunity_Type__c = 'Install New Service';
        opp.AccountId = a.Id;
        
        Insert opp;
        
       Quote q = new Quote();
        q.Name = 'Telecom Product or Service - Quote';
        q.ExpirationDate = opp.Quote_Expiration_Date__c;
        q.OpportunityId = opp.Id;
        
        Map<Id, Id> quoteMap = new Map<Id, Id>();

        QuoteAutoSyncUtil.syncQuote(quoteMap);
        
              
    }
    
}

but so far it is saying none of my lines are covered.  PLEASE HELP!!!  Thank you very much!
Best Answer chosen by DaNae Peterson
Rufus RodenRufus Roden
If you look at the code coverage would it be that you see that it's not going into the for loop in the class?  If that is so then the quoteMap must be empty. 
"quoteMap" is set up in the trigger based on the ExpirationDate not being null.
The ExpirationDate is setup in test class by assigning the opportunity field Quote_Expiration_Date__c but that field is not set up in the test data.  Unless there is other triggers/workflows in play then that field will remain null. 

If, in the test data, you explicitly set the ExpirationDate then your code coverage will be 100%.

As I don't have the fields you have I've cut down the test class a little.  The key difference is "q.ExpirationDate = Date.today();"
 
@isTest
public class AutoSyncQuote {

    public static testmethod void TestAutoSyncQuote() {

        Test.starttest();

        // Setup account
        Account a = new Account();
        a.Name = 'Test Account';
        Insert a;

        // Setup opportunity
        Opportunity opp = new Opportunity();
        opp.Name = 'Telecom Product or Service';
        opp.CloseDate = Date.today();
        opp.StageName = 'Quote Requested By Client';
        opp.AccountId = a.Id;
        Insert opp;

        // Setup quote
        Quote q = new Quote();
        q.Name = 'Telecom Product or Service - Quote';
        q.ExpirationDate = Date.today(); // opp.Quote_Expiration_Date__c;
        q.OpportunityId = opp.Id;
        insert q;

        Test.stopTest();
              
        // Assert tests
        Opportunity opportunity = [select SyncedQuoteId from Opportunity where id = :opp.id];

        System.assertequals(q.id, opportunity.SyncedQuoteId);

    }

}



 

All Answers

Rufus RodenRufus Roden
Try surrounding the test code with Test.startTest() and Test.stopTest() as described here (under Testing Future Methods):
https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_invoking_future_methods.htm
David ZhuDavid Zhu

You may use the following code as reference. BTW, in the future class, I don't understand why you use:

Integer oppSize = oppList.size();
            update oppList[oppSize -1 ];


instead of:
  update opplost;
 
@isTest
public class AutoSyncQuote {

    public static testmethod void TestAutoSyncQuote(){
	system.starttest();
       Account a = new Account();
        a.Name = 'Test Account';
        a.salesReach__Agent_Account_Company_Name__c = '001a000001DbY9F';
        a.salesReach__Agent_Contact_Name__c = '003a000001iM38p';
        a.Account_Status__c = 'Active';
        a.Diamond_Account__c = True;
        a.Net_One__c = False;
        
        Insert a;
        
       Opportunity opp = new Opportunity();
        opp.Name = 'Telecom Product or Service';
        opp.CloseDate = Date.today();
        opp.StageName = 'Quote Requested By Client';
        opp.Opportunity_Type__c = 'Install New Service';
        opp.AccountId = a.Id;
        
        Insert opp;


       Opportunity opp1 = new Opportunity();
        opp1.Name = 'Telecom Product or Service, No Expire date';
        opp1.CloseDate = Date.today();
        opp1.StageName = 'Quote Requested By Client';
        opp1.Opportunity_Type__c = 'Install New Service';
        opp1.AccountId = a.Id;
        
        Insert opp1;


	List<Quote> qs = new List<Quote>();
        
       Quote q = new Quote();
        q.Name = 'Telecom Product or Service - Quote';
        q.ExpirationDate = opp.Quote_Expiration_Date__c;
        q.OpportunityId = opp.Id;
	insert q;
	qs.add(q);

       Quote q1 = new Quote();  //expire date is null;
        q1.Name = 'Telecom Product or Service - Quote';
        q1.OpportunityId = opp1.Id;  //linked to opp1
	qs.add(q1);

        insert qs;

	system.stoptest();

	//verify opptunity result 
        Opportunity oresult = [select syncedquoteid from opportunity where id = :opp.id];
        Opportunity oresult1 = [select syncedquoteid from opportunity where id = :opp1.id];

	system.assertequals(q.id,oresult.syncedquotedid);
	system.assertequals(null,oresult1.syncedquotedid);
        
              
    }
    
}




 
DaNae PetersonDaNae Peterson
This works great for the trigger but zero for the class.  Do I need a whole new test class? 
David ZhuDavid Zhu
you dont' have to .
Rufus RodenRufus Roden
If you look at the code coverage would it be that you see that it's not going into the for loop in the class?  If that is so then the quoteMap must be empty. 
"quoteMap" is set up in the trigger based on the ExpirationDate not being null.
The ExpirationDate is setup in test class by assigning the opportunity field Quote_Expiration_Date__c but that field is not set up in the test data.  Unless there is other triggers/workflows in play then that field will remain null. 

If, in the test data, you explicitly set the ExpirationDate then your code coverage will be 100%.

As I don't have the fields you have I've cut down the test class a little.  The key difference is "q.ExpirationDate = Date.today();"
 
@isTest
public class AutoSyncQuote {

    public static testmethod void TestAutoSyncQuote() {

        Test.starttest();

        // Setup account
        Account a = new Account();
        a.Name = 'Test Account';
        Insert a;

        // Setup opportunity
        Opportunity opp = new Opportunity();
        opp.Name = 'Telecom Product or Service';
        opp.CloseDate = Date.today();
        opp.StageName = 'Quote Requested By Client';
        opp.AccountId = a.Id;
        Insert opp;

        // Setup quote
        Quote q = new Quote();
        q.Name = 'Telecom Product or Service - Quote';
        q.ExpirationDate = Date.today(); // opp.Quote_Expiration_Date__c;
        q.OpportunityId = opp.Id;
        insert q;

        Test.stopTest();
              
        // Assert tests
        Opportunity opportunity = [select SyncedQuoteId from Opportunity where id = :opp.id];

        System.assertequals(q.id, opportunity.SyncedQuoteId);

    }

}



 
This was selected as the best answer