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
Bruno LimaBruno Lima 

Test Class for Controller and Visualforce Pae

Hi guys!

I have a test class that I'm having a hard time to get it done and work. If any of you could help me, would be much appreciated.

This is the 1st Class:
public with sharing class opportunityProductEntryExtension {

    public Opportunity theOpp {get;set;}
    public String searchString {get;set;}
    public String searchstring2 {get;set;} 
    
    public opportunityLineItem[] shoppingCart {get;set;}
    public priceBookEntry[] AvailableProducts {get;set;}
    public Pricebook2 theBook {get;set;}   
    public string recordtypeidname {get;set;}
    public boolean checked {get;set;}

    public String Sections{get; set;}
            
    public String toSelect {get; set;}
    public String toUnselect {get; set;}
    public Decimal Total {get;set;}
    
    public Boolean overLimit {get;set;}
    public Boolean multipleCurrencies {get; set;}
    public List<SelectOption> getsectionnames {get;set;}
    
    private Boolean forcePricebookSelection = false;
    
    private opportunityLineItem[] forDeletion = new opportunityLineItem[]{};


    public opportunityProductEntryExtension(ApexPages.StandardController controller) {

        // Need to know if org has multiple currencies enabled
        multipleCurrencies = UserInfo.isMultiCurrencyOrganization();

        // Get information about the Opportunity being worked on
        if(multipleCurrencies)
            theOpp = database.query('select Id, Pricebook2Id, Pricebook2.Name, CurrencyIsoCode from Opportunity where Id = \'' + controller.getRecord().Id + '\' limit 1');
        else
            theOpp = [select Id, Pricebook2Id,AccountId,OwnerId, CloseDate, PriceBook2.Name from Opportunity where Id = :controller.getRecord().Id limit 1];
        
        //assegna il valore del recordtype alla variabile
       // recordtypeidname = theOpp.RecordType.name;
       // 
        // If products were previously selected need to put them in the "selected products" section to start with
        shoppingCart = [select Id, quantity,Family__c, unitprice,Area__c,TotalPrice,Refund__c,Supplier__c, ServiceDate,Change_Order__c, Discount,Description, Description__c, PriceBookEntryId, PriceBookEntry.Name, PriceBookEntry.IsActive, PriceBookEntry.Product2Id, PriceBookEntry.Product2.Name, PriceBookEntry.PriceBook2Id from opportunityLineItem where (OpportunityId=:theOpp.Id) ];
       
        // Check if Opp has a pricebook associated yet
        if(theOpp.Pricebook2Id == null){
            Pricebook2[] activepbs = [select Id, Name from Pricebook2 where isActive = true limit 2];
            if(activepbs.size() == 2){
                forcePricebookSelection = true;
                theBook = new Pricebook2();
            }
            else{
                theBook = activepbs[0];
            }
        }
        else{
            theBook = theOpp.Pricebook2;
        }
        
        if(!forcePricebookSelection)
            updateAvailableList();
    }
    
    // this is the 'action' method on the page
    public PageReference priceBookCheck(){
    
        // if the user needs to select a pricebook before we proceed we send them to standard pricebook selection screen
        if(forcePricebookSelection){        
            return changePricebook();
        }
        else{
        
            //if there is only one active pricebook we go with it and save the opp
            if(theOpp.pricebook2Id != theBook.Id){
                try{
                    theOpp.Pricebook2Id = theBook.Id;
                    update(theOpp);
                }
                catch(Exception e){
                    ApexPages.addMessages(e);
                }
            }
            
            return null;
        }
    }
       
    public String getChosenCurrency(){
    
        if(multipleCurrencies)
            return (String)theOpp.get('CurrencyIsoCode');
        else
            return '';
    }

    public void updateAvailableList() {
    
        // We dynamically build a query string and exclude items already in the shopping cart
        String qString = 'select Id, Pricebook2Id, IsActive, Product2.Name,  Product2.Family, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and Pricebook2Id = \'' + theBook.Id + '\'';
        
        String searchstring3 = Sections;
        if(multipleCurrencies)
            qstring += ' and CurrencyIsoCode = \'' + theOpp.get('currencyIsoCode') + '\'';
        
       
        // note that we are looking for the search string entered by the user in the name OR description
        // modify this to search other fields if desired
        if(searchString!=null){
            qString+= ' and (Product2.Name like \'%' + searchString + '%\' or Product2.Description like \'%' + searchString + '%\')';
        }
        if(searchString3!=null) if (searchString3!='All'){
            qString+= ' and (Product2.Name like \'%' + searchString3 + '%\' or Product2.Description like \'%' + searchString3 + '%\')';
        }
        
        Set<Id> selectedEntries = new Set<Id>();
        for(opportunityLineItem d:shoppingCart){
            selectedEntries.add(d.PricebookEntryId);
        }
        
        /*if(selectedEntries.size()>0){
            //String tempFilter = ' and Id not in (';
            for(Id i : selectedEntries){
                tempFilter+= '\'' + (String)i + '\',';
            }
            String extraFilter = tempFilter.substring(0,tempFilter.length()-1);
            extraFilter+= ')';
            
            qString+= extraFilter;
        }*/
        
        qString+= ' order by Product2.Name';
        qString+= ' limit 101';
        
        system.debug('qString:' +qString);        
        AvailableProducts = database.query(qString);
        
        // We only display up to 100 results... if there are more than we let the user know (see vf page)
        if(AvailableProducts.size()==101){
            AvailableProducts.remove(100);
            overLimit = true;
        }
        else{
            overLimit=false;
        }
    }
    
    public void addToShoppingCart(){
    
        // This function runs when a user hits "select" button next to a product
    
        for(PricebookEntry d : AvailableProducts){
            if((String)d.Id==toSelect){
                shoppingCart.add(new opportunityLineItem(OpportunityId=theOpp.Id, PriceBookEntry=d, unitprice=d.unitprice, PriceBookEntryId=d.Id));
                break;
            }
        }
        
        updateAvailableList();  
    }
    
    public void addAllToShoppingCart(){
    
        // This function runs when a user hits "select" button next to a product
    
        for(PricebookEntry d : AvailableProducts){
            shoppingCart.add(new opportunityLineItem(OpportunityId=theOpp.Id, PriceBookEntry=d,  PriceBookEntryId=d.Id));
           }
        
        
        updateAvailableList();  
    }
    

    public PageReference removeFromShoppingCart(){
    
        // This function runs when a user hits "remove" on an item in the "Selected Products" section
    
        Integer count = 0;
    
        for(opportunityLineItem d : shoppingCart){
            if((String)d.PriceBookEntryId==toUnselect){
            
                if(d.Id!=null)
                    forDeletion.add(d);
            
                shoppingCart.remove(count);
                break;
            }
            count++;
        }
        
        updateAvailableList();
        
        return null;
    }
    
    public PageReference onSave(){
    
    
        // If previously selected products are now removed, we need to delete them
        if(forDeletion.size()>0)
            delete(forDeletion);
            upsert(theOpp);
    
        // Previously selected products may have new quantities and amounts, and we may have new products listed, so we use upsert here
        try{
            if(shoppingCart.size()>0)
                upsert(shoppingCart);
                upsert(theOpp);
        }
        catch(Exception e){
            ApexPages.addMessages(e);
            return null;
        }  
           
        // After save return the user to the Opportunity
        return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id'));
    }
    
    public PageReference onCancel(){

        // If user hits cancel we commit no changes and return them to the Opportunity   
        return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id'));
    }
    
    public PageReference changePricebook(){
    
        // This simply returns a PageReference to the standard Pricebook selection screen
        // Note that is uses retURL parameter to make sure the user is sent back after they choose
    
        PageReference ref = new PageReference('/oppitm/choosepricebook.jsp');
        ref.getParameters().put('id',theOpp.Id);
        ref.getParameters().put('retURL','/apex/opportunityProductEntry?id=' + theOpp.Id);
        
        return ref;
    }
   
    public List<SelectOption> getsectionnames(){ 
         List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('Baseboards','Baseboards'));
        options.add(new SelectOption('Bathroom','Bathroom'));
        options.add(new SelectOption('Bath Tubs','Bath Tubs'));
        options.add(new SelectOption('Cabinets','Cabinets'));
        options.add(new SelectOption('Counter Tops','Counter Tops'));
        options.add(new SelectOption('Demolition','Demolition'));
        options.add(new SelectOption('Doors','Doors'));
        options.add(new SelectOption('Drywall','Drywall'));
        options.add(new SelectOption('Electrical','Electrical'));
        options.add(new SelectOption('Faucets','Faucets'));
        options.add(new SelectOption('Flooring','Flooring'));
        options.add(new SelectOption('HVAC','HVAC'));
        options.add(new SelectOption('Labour','Labour'));
        options.add(new SelectOption('Paneling / Moulds','Paneling / Moulds'));
        options.add(new SelectOption('Plumbing','Plumbing'));
        options.add(new SelectOption('Showers','Showers'));
        options.add(new SelectOption('Sinks','Sinks'));
        options.add(new SelectOption('Tiles/ Tiling','Tiles/ Tiling'));
        options.add(new SelectOption('Hardware','Hardware'));
       // List<Sections_Picklist__c> Sectionlist = new List<Sections_Picklist__c>();  
        /*Sectionlist = [Select  Family FROM Product2 ORDER BY name];
          for (Integer j=0;j<sectionlist.size();j++)  { 
                 options.add(new SelectOption(sectionlist[j].Family,sectionlist[j].Family));  
                 }*/
           return options;
      }
    
    public with sharing class opportunityProductRedirectExtension {

    Id oppId;

    // we are extending the OpportunityLineItem controller, so we query to get the parent OpportunityId
    public opportunityProductRedirectExtension(ApexPages.StandardController controller) {
        oppId = [select Id, OpportunityId from OpportunityLineItem where Id = :controller.getRecord().Id limit 1].OpportunityId;
    }
    
    // then we redirect to our desired page with the Opportunity Id in the URL
    public pageReference redirect(){
        return new PageReference('/apex/opportunityProductEntry?id=' + oppId);
    }

}
    
}
The second class:
 
public with sharing class opportunityProductRedirectExtension {

    public opportunityProductRedirectExtension(ApexPages.StandardController controller) {

    }

}

Visual force page:
 
<apex:page standardController="Opportunity" extensions="opportunityProductEntryExtension" sidebar="false" action="{!priceBookCheck}" lightningStylesheets="true">

    <apex:sectionHeader Title="Manage {!$ObjectType.Product2.LabelPlural}" subtitle="{!opportunity.Name}"/>
    <apex:messages style="color:red"/>
<!--apex:outputText value="{!opportunity.RecordType.Name}"/-->
        
    <style> 
        .search{
            font-size:14pt;
            margin-right: 20px;    
        }
        .fyi{
            color:red;
            font-style:italic;
        }
        .label{ 
            margin-right:10px;
            font-weight:bold;
        }
    </style>
    
    <script type='text/javascript'>
    
        // This script assists the search bar functionality
        // It will execute a search only after the user has stopped typing for more than 1 second
        // To raise the time between when the user stops typing and the search, edit the following variable:
        
        var waitTime = 1;
        
    
        var countDown = waitTime+1;
        var started = false;
        
        function resetTimer(){
        
            countDown=waitTime+1;
            
            if(started==false){
                started=true;
                runCountDown();
            }
        }
        
        function runCountDown(){
        
            countDown--;
            
            if(countDown<=0){
                fetchResults();
                started=false;
            }
            else{
                window.setTimeout(runCountDown,1000);
            }
        }
    
    </script>
   
  
    <apex:form >
    
        <apex:outputPanel id="mainBody">
        
            <!--apex:outputLabel styleClass="label">PriceBook: </apex:outputLabel>
            <apex:outputText value="{!theBook.Name}"/>&nbsp;
             <apex:commandLink action="{!changePricebook}" value="change" immediate="true"/-->
            <br/>
            <!-- not everyone is using multi-currency, so this section may or may not show -->
            <!--apex:outputPanel rendered="{!multipleCurrencies}"-->
            <!--
                <apex:outputLabel styleClass="label">Currency: </apex:outputLabel>
                <apex:outputText value="{!chosenCurrency}"/>
                <br/>
            </apex:outputPanel>
            <br/>
            
<!-- this is the upper table... a.k.a. the "Shopping Cart"-->

            <!-- notice we use a lot of $ObjectType merge fields... I did that because if you have changed the labels of fields or objects it will reflect your own lingo -->
            <apex:pageBlock title="Selected {!$ObjectType.Product2.LabelPlural}" id="selected">
                       
                <apex:pageblockTable value="{!shoppingCart}" var="s">
                
                    <apex:column >
                        <apex:commandLink value="Remove" action="{!removeFromShoppingCart}" reRender="selected,searchResults" immediate="true">
                            <!-- this param is how we send an argument to the controller, so it knows which row we clicked 'remove' on -->
                            <apex:param value="{!s.PriceBookEntryId}" assignTo="{!toUnselect}" name="toUnselect"/>
                        </apex:commandLink>
                    </apex:column>
                    <!--apex:column width="25px">
                    <apex:inputcheckbox value="{!checked}"/>
                    </apex:column> -->
                    
                    <apex:column headerValue="{!$ObjectType.Product2.LabelPlural}" value="{!s.PriceBookEntry.Product2.Name}"/>
                    
                  <!--  <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Profile__c.Label}" rendered="{!opportunity.Market__c != 'MTS DATA'}">
                                       
                        <apex:inputField value="{!s.Profile_CAT__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS Cash Markets'}" />
                        <!-- apex:inputField value="{!s.Profile_CAT__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS Live'}" /
                        <apex:inputField value="{!s.Profile_MMF__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS Repo Markets'}" />
                        <apex:inputField value="{!s.Profile_BV__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS Bondvision'}" />    
                        <apex:inputField value="{!s.Profile_ACM__c}" style="width:110px" required="true" onkeyup="refreshTotals();" rendered="{!opportunity.Market__c = 'MTS ACM'}" />    
                     </apex:column> -->
                    
                      <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Quantity.Label}">
                        <apex:inputField value="{!s.Quantity}" style="width:70px" required="true" onkeyup="refreshTotals();" />
                    </apex:column>

                      <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.UnitPrice.Label}" >
                        <apex:inputField value="{!s.UnitPrice}" style="width:70px" required="true" onkeyup="refreshTotals();" />
                    </apex:column>
                                                               
                    <apex:column headerValue="{!$ObjectType.OpportunityLineItem.Fields.Description__c.Label}">
                        <apex:inputField value="{!s.Description__c}" required="false"/>
                    </apex:column>
                    
                </apex:pageblockTable>
            
            
                <apex:pageBlockButtons >
                    <apex:commandButton action="{!onSave}" value="Save"/>
                    <apex:commandButton action="{!onCancel}" value="Cancel" immediate="true"/>
                    <!--apex:commandButton action="{!onadd}" value="Add Selected"/-->
                </apex:pageBlockButtons>
            
            </apex:pageBlock> 
    
<!-- this is the lower table: search bar and search results -->
    
            <apex:pageBlock >
            
                <apex:outputPanel styleClass="search">
                    Search for {!$ObjectType.Product2.LabelPlural} 
                </apex:outputPanel>

                <apex:actionRegion renderRegionOnly="false" immediate="true"> 
                
                    <apex:actionFunction name="fetchResults" action="{!updateAvailableList}" reRender="searchResults" status="searchStatus"/>
                    
                    <!-- here we invoke the scripting to get out fancy 'no button' search bar to work -->
                    <apex:inputText value="{!searchString}" onkeydown="if(event.keyCode==13){this.blur();}else{resetTimer();}" style="width:300px" />
                         <apex:actionFunction name="fetchResults1" action="{!updateAvailableList}" reRender="searchResults" status="searchStatus"/>

               <!-- <apex:outputPanel styleClass="search" >
                    Area
                </apex:outputPanel>-->

                         
                         <apex:outputlabel value="Sections" for="values"/>
                         <apex:selectList value="{!Sections}" size="1" id="values">
                             <apex:actionSupport event="onchange" action="{!updateAvailableList}" reRender="searchResults" />
                             <apex:selectOptions value="{!Sectionnames}"/>     
                          </apex:selectList>
                <apex:outputPanel styleClass="search">

                </apex:outputPanel> 
                          
                          <apex:commandButton action="{!addAllToShoppingCart}" value="Add All Products" reRender="selected,searchResults" immediate="true"/>

                    &nbsp;&nbsp;
                    <i>
                      <!-- actionStatus component makes it easy to let the user know when a search is underway -->
                      <apex:actionStatus id="searchStatus" startText="searching..." stopText=" "/>
                      </i>
                    </apex:actionRegion>
            
                <br/>
            
                <apex:outputPanel id="searchResults">
                
                    <apex:pageBlockTable value="{!AvailableProducts}" var="a">
                    
                    <apex:column width="25px"> 
                    <apex:inputcheckbox value="{!checked}"/>
                    </apex:column> 
                    
                        <apex:column headerValue="{!$ObjectType.Product2.Fields.Name.Label}" value="{!a.Product2.Name}" />
                        <apex:column headerValue="{!$ObjectType.Product2.Fields.Family.Label}" value="{!a.Product2.Family}"/>
                        <apex:column headerValue="{!$ObjectType.Product2.Fields.Description.Label}" value="{!a.Product2.Description}"/>

                        <apex:column >
                            <!-- command button in a column... neato -->
                            <apex:commandButton value="Select" action="{!addToShoppingCart}" reRender="selected,searchResults" immediate="true">
                                <!-- again we use apex:param to be able to tell the controller which row we are working with -->
                                <apex:param value="{!a.Id}" assignTo="{!toSelect}" name="toSelect"/>
                            </apex:commandButton>
                        </apex:column>
                        
                    </apex:pageBlockTable>
                    
                    <!-- We put up a warning if results exceed 100 rows -->
                    <apex:outputPanel styleClass="fyi" rendered="{!overLimit}">
                        <br/>
                        Your search returned over 100 results, use a more specific search string if you do not see the desired {!$ObjectType.Product2.Label}.
                        <br/>
                    </apex:outputPanel>
                </apex:outputPanel>
            </apex:pageBlock>
        </apex:outputPanel>
    </apex:form>
    </apex:page>

Test class:
 
@istest
private class opportunityProductEntryTests{

    static testMethod void theTests(){

   //     TestUtilities tu = TestUtilities.generateTest();
// this is an external class that will generate a number of records I will query below.
// I suggest creating a TestUtility class to be called by your test class instead of creating the 
// records in each test class.
// This to save time, code and providing a clear code organization.

        // Find standard pricebook ID
        Id pricebookId = Test.getStandardPricebookId();

       
        
        //Create new product
        Product2 p = new Product2(Name='test', IsActive = true, Family = 'Plumbing');
        insert p;
        
         //Creating pricebook entry
        PricebookEntry standardPrice = new PricebookEntry(
            Pricebook2Id = pricebookId, Product2Id = p.Id,
            UnitPrice = 10000, IsActive = true);
        insert standardPrice;
        
        //Create new Account
        Account acc = new Account (Name='Focus', ZuminLocation__c='NW Mississauga');
        insert acc;
        
        //Create New Opportunity
       Opportunity opp = new Opportunity (Name = 'test',Pricebook2Id= pricebookId,  AccountId = acc.id, StageName ='Closed Won', CloseDate = system.today());
        insert opp;
        
        //Create Opp product 
        OpportunityLineItem opp1 = new OpportunityLineItem(OpportunityId =opp.id, Product2Id = p.id, UnitPrice =0, Quantity = 1);
        insert opp1;
        
        // Create new Opp Line Item
        OpportunityLineItem oli = [select Id, PricebookEntryId, PricebookEntry.Pricebook2Id, PricebookEntry.Name, PriceBookEntry.Product2Id, OpportunityId, Opportunity.AccountId FROM OpportunityLineItem ];
        system.debug('value dell id :' + oli.id);      
                
        ////////////////////////////////////////
        //  test opportunityProductEntry
        ////////////////////////////////////////
        
        // load the page   
        Test.StartTest();
      
        PageReference pageRef = Page.NewProducts;
        pageRef.getParameters().put('Id',opp.Id);
        Test.setCurrentPageReference(pageRef);
        
      //  Apexpages.StandardController stdController = new Apexpages.StandardController(opp1);
      //  opportunityProductEntryExtension controller = new opportunityProductEntryExtension(stdController);
        
        ApexPages.StandardController sc = new ApexPages.standardController(new Opportunity());
// create an instance of the controller
opportunityProductEntryExtension co = new opportunityProductEntryExtension(sc);
        
        String options = 'Plumbing';
        sc.save();
        sc.edit();
        sc.view();
        sc.cancel();
        sc.getId();
        sc.getRecord();
        
       Test.StopTest();
        
        //
        // load the extension
      //  opportunityProductEntryExtension oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(opp1));
        
       /* // test 'getChosenCurrency' method
        if(UserInfo.isMultiCurrencyOrganization())
            System.assert(oPEE.getChosenCurrency()!='');
        else
            System.assertEquals(oPEE.getChosenCurrency(),'');


        ////////////////////////////////////////
        //  test redirect page
        ////////////////////////////////////////
        
   

      opportunityProductRedirectExtension(new ApexPages.StandardController(oli2[0]));
     
    }
}