+ Start a Discussion
Waqas AliWaqas Ali 

Writing unit test for Wrapper class and contact roles

I have a button in opportunity tab , which call this myclass. Here i am changing the status of acyive contacts in vf page as "Expired or Lapse" and copying the contact roles in newyly created opportunity and contract. 
public class myclass{
 
    
    public Opportunity o;
    String theId = ApexPages.currentPage().getParameters().get('id');
    List<OpportunityContactRole> oppRoles;
    Contract[] myContract;
    Opportunity[] myOpportunity;
    
    
    public List<WrapperSObject> records {get; set;}
    public Contract con {get; set;}
    public String selectedValue {get; set;}
    public  myclass(ApexPages.StandardController stdController) {
        this.o = (Opportunity)stdController.getRecord();
    }
     
    public PageReference autoRun() {
 
        String theId = ApexPages.currentPage().getParameters().get('id');
         if (theId == null) {
            return null;
        }
       o=[select id, name, AccountId,  StageName, Type, CloseDate from Opportunity where id =:theId];
 
records = new List<WrapperSObject>();
 for (Contract c : [select id, Name, AccountId, StartDate, Status, ContractNumber from Contract where Status='Activated'  ])
 {
 records.add(new WrapperSObject(c, getOptions(), 'Activated'));
 }
     return null;
          
}
 public PageReference MainMethod() {
 
  try{
       o=[select id, name, AccountId,  StageName, Type, CloseDate from Opportunity where id =:theId];
 
             
             //Create the contract
            Contract c = new Contract(
                ,StartDate=o.CloseDate
                ,AccountId = o.AccountId
                ,Name = o.Name
                );
            insert c;
       
       
       //copy contact roles

            oppRoles = [SELECT Id, OpportunityID, ContactID, IsPrimary, Role FROM OpportunityContactRole WHERE OpportunityId = :theId LIMIT 10000];
             myContract = [SELECT Id, ContractNumber, StartDate, EndDate,
                           AccountId, ContractTerm, Status, CustomerSignedId FROM Contract WHERE Id = :c.Id LIMIT 1];
             
             if ( ! oppRoles.isEmpty()) {
                    myContract[0].CustomerSignedId = oppRoles.get(0).ContactId;
              }  
              
              if ( ! oppRoles.isEmpty()){
                    List<ContractContactRole> conRoles = new List<ContractContactRole>();
                      
                      for (OpportunityContactRole oppRole : oppRoles)
                        { 
                             conRoles.add(new ContractContactRole(
                             ContactId = oppRole.ContactId,
                             IsPrimary = oppRole.IsPrimary,
                             Role = oppRole.Role,
                             ContractId = myContract[0].Id));                       
                         }
                         insert conRoles;
              }
                
     //Create new Oppertunity
             Opportunity opp = new Opportunity(
                     Name = 'TESTACCOUNT_test july' +'Date.today()'
                     ,CloseDate=Date.today()
                     ,StageName= 'Renewal'
                     ,Type='EnerLead Renewal'
                     ,Description='Newly created Oppertunity'
                     ,Product_Family__c='EnerLead' 
                );
            insert opp;
        //Copy roles of old opportunity to new
            
             myOpportunity = [SELECT Id, StageName, Type FROM Opportunity WHERE Id = :opp.Id LIMIT 1];
             
          
              
              if ( ! oppRoles.isEmpty()){
                    List<OpportunityContactRole> newoppRoles = new List<OpportunityContactRole>();
                      
                      for (OpportunityContactRole oppRole : oppRoles)
                        { 
                             newoppRoles.add(new OpportunityContactRole(
                             ContactId = oppRole.ContactId,
                             IsPrimary = oppRole.IsPrimary,
                             Role = oppRole.Role,
                             OpportunityId = myOpportunity[0].Id));                       
                         }
                         insert newoppRoles;
              
              }          
   
//try section     
}catch(QueryException e){
      ApexPages.Message msg = new Apexpages.Message(ApexPages.Severity.Warning,'Something is wrong' );
      ApexPages.addmessage(msg);
}catch(DMLException e){}
    
        return null;        
  }


// To Update contracts 
 public PageReference back() {
       List<Contract> contractToBeUpdate = new List<Contract>();
    for(WrapperSObject wrapper : records){
        wrapper.con.status = wrapper.selectedValue;
        contractToBeUpdate.add(wrapper.con);
    }
    update contractToBeUpdate;
    PageReference pageRef ;    
     return pageRef= MainMethod();
  }
 


public class WrapperSObject {
public Contract con {get; set;}
 public List < SelectOption > options {get; set;}
        public String selectedValue {get; set;}
  
     
    public WrapperSObject( Contract c,List < SelectOption > options, String selectedValue) {
    con=c;
     this.options = options;
     this.selectedValue = selectedValue;
     }
  
  }

public List < SelectOption > getOptions() {
List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('Activated','Activated'));
        options.add(new SelectOption('Expired','Expired'));
        options.add(new SelectOption('LAPSE','Lapse'));
        return options;
    }
  
     

}

Here is my test class
I have very less code coverage.
@isTest
private class myclassTest {
    private static testMethod void testAutoRun() {

    
        Account acc = new Account(Name='Abce');
  insert acc;
 
  Opportunity  testOppty = new Opportunity();
  testOppty.name='testOppty';
  testOppty.AccountId=acc.id;
  testOppty.CloseDate=System.today();
  testOppty.StageName= 'Closed Won';
  testOppty.Type='EnerLead Renewal';
  testOppty.Description='Newly created Oppertunity';
  testOppty.Product_Family__c='EnerLead'; 
  insert testOppty;
  
        //Create the Order
                    Order odr = new Order(  
                    OpportunityId=testOppty.id
                    ,AccountId = testOppty.AccountId
                    ,Name = testOppty.Name
                    ,EffectiveDate=Date.today()
                    ,Status='Draft'
                    );
        insert odr;
                  Contract c = new Contract(
                ,StartDate=testOppty.CloseDate
                ,AccountId = testOppty.AccountId
                ,Name = testOppty.Name
                );
            insert c;
  
  
        
        test.startTest();
        
            PageReference pageRef = Page.myclass;
            Test.setCurrentPage(pageRef);
            
            pageRef.getParameters().put('id',testOppty.id);
            ApexPages.StandardController sc = new ApexPages.standardController(testOppty);
            
            myclass  controller = new myclass(sc);
            controller.autoRun();
            controller.back();
            controller.MainMethod();
        test.stopTest();
}
}
I want to know how to write unit test for following sections 
  • "copying contact roles from old to new opportunity and contract"
  • "Wrapper class and last getoptions() selection method"?
Guys any help. ? please
Best Answer chosen by Waqas Ali
William TranWilliam Tran
Waqas, I found out why "activated" failed -> SF does not allow you to create activated contract directly

try this:
 
Contract c = new Contract(
            StartDate=testOppty.CloseDate
            ,AccountId = testOppty.AccountId
            ,Name = testOppty.Name
            ,Status='Draft'
        );
        insert c;
        
        c.status ='Activated';
        update c;

This should get you over 90%.  The rest are error conditions and null condition for example try this- just don't pass the Id by commenting it out so null is return.
 
test.startTest();
         try
         {
            PageReference pageRef = Page.myclass;
            Test.setCurrentPage(pageRef);
            pageRef.getParameters().put('id',testOppty.id);
            ApexPages.StandardController sc = new ApexPages.standardController(testOppty);
            myclass  controller = new myclass(sc);
            controller.autoRun();
            controller.back();
            controller.MainMethod();
            controller.MainMethod();
            controller.MainMethod();
        }
        catch(Exception ee)
        {
            
        }   
        
          try
         {
            PageReference pageRef = Page.myclass;
            Test.setCurrentPage(pageRef);
            //pageRef.getParameters().put('id',testOppty.id);
            ApexPages.StandardController sc = new ApexPages.standardController(testOppty);
            myclass  controller = new myclass(sc);
            controller.autoRun();
            controller.back();
            controller.MainMethod();
            controller.back();

        }
        catch(Exception ee)
        {
            
        }   
        
        
        
        
        
        test.stopTest();

Thx

All Answers

Amit Chaudhary 8Amit Chaudhary 8
Hi,

Please try below test class. I hope that will help u
@isTest
private class myclassTest 
{
    private static testMethod void testAutoRun() 
	{
        Account acc = new Account(Name='Abce');
		insert acc;
		
		Contact cont = new Contact();
		cont.FirstName ='FiestName';
		cont.LastName ='LastName';
		cont.accountid =acc.id;
		insert cont;
 
		Opportunity  testOppty = new Opportunity();
			testOppty.name='testOppty';
			testOppty.AccountId=acc.id;
			testOppty.CloseDate=System.today();
			testOppty.StageName= 'Closed Won';
			testOppty.Type='EnerLead Renewal';
			testOppty.Description='Newly created Oppertunity';
			testOppty.Product_Family__c='EnerLead'; 
		insert testOppty;
		
		OpportunityContactRole ocRole = new OpportunityContactRole (ContactId = cont.id, OpportunityId=testOppty.Id, Role='Decision Maker',IsPrimary=TRUE));
		insert ocRole;
  
        //Create the Order
		Order odr = new Order(  
			OpportunityId=testOppty.id
			,AccountId = testOppty.AccountId
			,Name = testOppty.Name
			,EffectiveDate=Date.today()
			,Status='Draft'
		);
		insert odr;
		
		Contract c = new Contract(
			,StartDate=testOppty.CloseDate
			,AccountId = testOppty.AccountId
			,Name = testOppty.Name
			.Status='Activated'
		);
		insert c;
        
        test.startTest();
		 try
		 {
            PageReference pageRef = Page.myclass;
            Test.setCurrentPage(pageRef);
            pageRef.getParameters().put('id',testOppty.id);
            ApexPages.StandardController sc = new ApexPages.standardController(testOppty);
            myclass  controller = new myclass(sc);
            controller.autoRun();
            controller.back();
            controller.MainMethod();
		}
		catch(Exception ee)
		{
			
		}	
        test.stopTest();
	}
}
Please check below blog for more information on test classes
http://amitsalesforce.blogspot.in/2015/06/best-practice-for-test-classes-sample.html


Please follow below salesforce Best Practice for Test Classes :-

1. Test class must start with @isTest annotation if class class version is more than 25
2. Test environment support @testVisible , @testSetUp as well
3. Unit test is to test particular piece of code working properly or not .
4. Unit test method takes no argument ,commit no data to database ,send no email ,flagged with testMethod keyword .
5. To deploy to production at-least 75% code coverage is required 
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the  percentage of code coverage ,we should make sure that every use case should covered including positive, negative,bulk and single record .
Single Action -To verify that the the single record produces the correct an expected result .
Bulk action -Any apex record trigger ,class or extension must be invoked for 1-200 records .
Positive behavior : Test every expected behavior occurs through every expected permutation , i,e user filled out every correctly data and not go past the limit .
Negative Testcase :-Not to add future date , Not to specify negative amount.
Restricted User :-Test whether a user with restricted access used in your code .10. Test class should be annotated with @isTest .
11 . @isTest annotation with test method  is equivalent to testMethod keyword .
12. Test method should static and no void return type .
13. Test class and method default access is private ,no matter to add access specifier .
14. classes with @isTest annotation can't be a interface or enum .
15. Test method code can't be invoked by non test request .
16. Stating with salesforce API 28.0 test method can not reside inside non test classes .
17. @Testvisible annotation to make visible private methods inside test classes.
18. Test method can not be used to test web-service call out . Please use call out mock .
19. You can't  send email from test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType, ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version eailer .
22. Accessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,'ResourceName').
23. Create TestFactory class with @isTest annotation to exclude from organization code size limit .
24. @testSetup to create test records once in a method  and use in every test method in the test class .
25. We can run unit test by using Salesforce Standard UI,Force.com IDE ,Console ,API.
26. Maximum number of test classes run per 24 hour of period is  not grater of 500 or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing are not taken into account . So we need to use system.runAs to enforce record sharing .
28. System.runAs will not enforce user permission or field level permission .
29. Every test to runAs count against the total number of DML issued in the process .


Please let us know if this post will help you

Thanks,
Amit Chaudhary
Waqas AliWaqas Ali

Amit Chaudhary it helped a lot . Unit test for Contact roles are getiing covered, but still wrapper class is not. 

When i put  ,Status='Activated' , its gives insertion Error and my code covergae is 72% still.  Need few more. 

Thank's Amit. 

William TranWilliam Tran

Waqas, does your code work?  

It looks to have too many public variables declared with overlapping gets.

Anyway, instead fo revamping the whole thing, try this WrapperSObject first (see below):

I only changed 

public List < SelectOption > options {get; set;}
to just 
List < SelectOption > options;  

since you already have a get method and it does not look like you need a set method.  Since you declared it twice your getOptions code is never called and thus the error and low coverage. 

IF List < SelectOption > options;   gives you compilation error, you can put Public back such as public List < SelectOption > options; 
But I don't see any place where you would need it to be public.

If my hunch is right, this may solve both your insertion issue and test coverage issue.

There's other things you can do to make your code more consistent/readable but we can address that another time.


Thx

public class WrapperSObject {


	public Contract con {get; set;}
	List < SelectOption > options;
        public String selectedValue {get; set;}
  
     
    	public WrapperSObject( Contract c,List < SelectOption > options, String selectedValue) {
    	con=c;
     	this.options = options;
     	this.selectedValue = selectedValue;
     	}
  
  }

	public List < SelectOption > getOptions() {
	List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('Activated','Activated'));
        options.add(new SelectOption('Expired','Expired'));
        options.add(new SelectOption('LAPSE','Lapse'));
        return options;
    }
  
     

}
William TranWilliam Tran
It's hard to see but the code looks to have one too many braces if you look at the code by itself, but you you cut and paste (like I did) you should be fine. but just to be safe,  just change:

public List < SelectOption > options {get; set;}

to 

List < SelectOption > options;  

Save/compile and run.

thx.
Waqas AliWaqas Ali
no effect on code coverage.
William TranWilliam Tran
Ok, it looks like the getOptions is not part of the wrapper class but the main Myclass.  You can put back the 

public List < SelectOption > options {get; set;}    statement.

Is there a reason why you run the back before th MainMethod in you test class?

46             controller.autoRun();
47             controller.back();
48             controller.MainMethod();


also for this:
 
public WrapperSObject( Contract c,List < SelectOption > options, String selectedValue) {
    con=c;
     this.options = options;
     this.selectedValue = selectedValue;
     }

You might want change to this.con =c;

Thx
Amit Chaudhary 8Amit Chaudhary 8
Hi Waqas,

Please try below code. I hope that will help you.
@isTest
private class myclassTest 
{
    private static testMethod void testAutoRun() 
	{
        Account acc = new Account(Name='Abce');
		insert acc;
		
		Contact cont = new Contact();
		cont.FirstName ='FiestName';
		cont.LastName ='LastName';
		cont.accountid =acc.id;
		insert cont;
 
		Opportunity  testOppty = new Opportunity();
			testOppty.name='testOppty';
			testOppty.AccountId=acc.id;
			testOppty.CloseDate=System.today();
			testOppty.StageName= 'Closed Won';
			testOppty.Type='EnerLead Renewal';
			testOppty.Description='Newly created Oppertunity';
			testOppty.Product_Family__c='EnerLead'; 
		insert testOppty;
		
		OpportunityContactRole ocRole = new OpportunityContactRole (ContactId = cont.id, OpportunityId=testOppty.Id, Role='Decision Maker',IsPrimary=TRUE));
		insert ocRole;
  
        //Create the Order
		Order odr = new Order(  
			OpportunityId=testOppty.id
			,AccountId = testOppty.AccountId
			,Name = testOppty.Name
			,EffectiveDate=Date.today()
			,Status='Draft'
		);
		insert odr;
		
		Contract c = new Contract(
			,StartDate=testOppty.CloseDate
			,AccountId = testOppty.AccountId
			,Name = testOppty.Name
			.Status='Activated'
		);
		insert c;
        
        test.startTest();
		 try
		 {
            PageReference pageRef = Page.myclass;
            Test.setCurrentPage(pageRef);
            pageRef.getParameters().put('id',testOppty.id);
            ApexPages.StandardController sc = new ApexPages.standardController(testOppty);
            myclass  controller = new myclass(sc);
            controller.autoRun();
            controller.back();
            controller.MainMethod();
			// You can try below code to inc the code coverage. If you can update the contract Status as activated then below wrapper and fun will cover automatic. In mean time you can try below code
			List < SelectOption > lst = controller.getOptions();
			controller. records.add(new WrapperSObject(c, lst , 'Activated'));
		}
		catch(Exception ee)
		{
			
		}	
        test.stopTest();
	}
}



// You can try below code to inc the code coverage. If you can update the contract Status as activated then below wrapper and fun will cover automatic. In mean time you can try below code
List < SelectOption > lst = controller.getOptions();
controller. records.add(new WrapperSObject(c, lst , 'Activated'));

NOTE :- above two line should be come after autoRun method.

Please let us know if this will help u
Waqas AliWaqas Ali

List < SelectOption > lst = controller.getOptions();is covering selection method.
My code coverage is now 89%. but still records.add(new WrapperSObject(c, getOptions(), 'Activated')); is not getting covered. 

When i put  Status='Activated' in contract it gives insertion error. I need 100% code coverage. 

William TranWilliam Tran
Waqas,  also how did you get this to compile?


//Create the contract

Contract c = new Contract( ,StartDate=o.CloseDate ,AccountId = o.AccountId ,Name = o.Name ); insert c;


there's a comma right after the (  --> "Contract(,"

thx.
William TranWilliam Tran
Okay, I reviewed your code from top down -line by line

Here's some of your problems:

1) Activation error 

Contract c = new Contract( ,StartDate=testOppty.CloseDate ,AccountId = testOppty.AccountId ,Name = testOppty.Name .Status='Activated' ); insert c;

you used dot status, it should be comma status so changed .Status= to ,status=

2)         OpportunityContactRole ocRole = new OpportunityContactRole (ContactId = cont.id,OpportunityId=testOppty.Id, Role='Decision Maker',IsPrimary=TRUE));

An extra ) is there.


Now looking back, this is actually Amit's code :-)

Anyway, fix these and try again.

Please post your latest code, I am having a hard time know what code to look at anymore :-)

Thx
Waqas AliWaqas Ali
These are syntax error, i have removed before compiling. I just need idea how to do things
William TranWilliam Tran
Waqas, I found out why "activated" failed -> SF does not allow you to create activated contract directly

try this:
 
Contract c = new Contract(
            StartDate=testOppty.CloseDate
            ,AccountId = testOppty.AccountId
            ,Name = testOppty.Name
            ,Status='Draft'
        );
        insert c;
        
        c.status ='Activated';
        update c;

This should get you over 90%.  The rest are error conditions and null condition for example try this- just don't pass the Id by commenting it out so null is return.
 
test.startTest();
         try
         {
            PageReference pageRef = Page.myclass;
            Test.setCurrentPage(pageRef);
            pageRef.getParameters().put('id',testOppty.id);
            ApexPages.StandardController sc = new ApexPages.standardController(testOppty);
            myclass  controller = new myclass(sc);
            controller.autoRun();
            controller.back();
            controller.MainMethod();
            controller.MainMethod();
            controller.MainMethod();
        }
        catch(Exception ee)
        {
            
        }   
        
          try
         {
            PageReference pageRef = Page.myclass;
            Test.setCurrentPage(pageRef);
            //pageRef.getParameters().put('id',testOppty.id);
            ApexPages.StandardController sc = new ApexPages.standardController(testOppty);
            myclass  controller = new myclass(sc);
            controller.autoRun();
            controller.back();
            controller.MainMethod();
            controller.back();

        }
        catch(Exception ee)
        {
            
        }   
        
        
        
        
        
        test.stopTest();

Thx
This was selected as the best answer
Waqas AliWaqas Ali
Thank You William Tran. It helped a lot.